]> granicus.if.org Git - strace/blob - system.c
Experimental support for "detach on execve" feature
[strace] / system.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  *      $Id$
31  */
32
33 #include "defs.h"
34
35 #define _LINUX_SOCKET_H
36 #define _LINUX_FS_H
37
38 #define MS_RDONLY        1      /* Mount read-only */
39 #define MS_NOSUID        2      /* Ignore suid and sgid bits */
40 #define MS_NODEV         4      /* Disallow access to device special files */
41 #define MS_NOEXEC        8      /* Disallow program execution */
42 #define MS_SYNCHRONOUS  16      /* Writes are synced at once */
43 #define MS_REMOUNT      32      /* Alter flags of a mounted FS */
44 #define MS_MANDLOCK     64      /* Allow mandatory locks on an FS */
45 #define MS_DIRSYNC      128     /* Directory modifications are synchronous */
46 #define MS_NOATIME      1024    /* Do not update access times. */
47 #define MS_NODIRATIME   2048    /* Do not update directory access times */
48 #define MS_BIND         4096
49 #define MS_MOVE         8192
50 #define MS_REC          16384
51 #define MS_SILENT       32768
52 #define MS_POSIXACL     (1<<16) /* VFS does not apply the umask */
53 #define MS_UNBINDABLE   (1<<17) /* change to unbindable */
54 #define MS_PRIVATE      (1<<18) /* change to private */
55 #define MS_SLAVE        (1<<19) /* change to slave */
56 #define MS_SHARED       (1<<20) /* change to shared */
57 #define MS_RELATIME     (1<<21)
58 #define MS_KERNMOUNT    (1<<22)
59 #define MS_I_VERSION    (1<<23)
60 #define MS_STRICTATIME  (1<<24)
61 #define MS_BORN         (1<<29)
62 #define MS_ACTIVE       (1<<30)
63 #define MS_NOUSER       (1<<31)
64 #define MS_MGC_VAL      0xc0ed0000      /* Magic flag number */
65 #define MS_MGC_MSK      0xffff0000      /* Magic flag mask */
66
67 #include <sys/socket.h>
68 #include <netinet/in.h>
69 #include <arpa/inet.h>
70
71
72 #ifdef HAVE_LINUX_CAPABILITY_H
73 #include <linux/capability.h>
74 #endif
75
76 #ifdef HAVE_ASM_CACHECTL_H
77 #include <asm/cachectl.h>
78 #endif
79
80 #ifdef HAVE_LINUX_USTNAME_H
81 #include <linux/utsname.h>
82 #endif
83
84 #ifdef HAVE_ASM_SYSMIPS_H
85 #include <asm/sysmips.h>
86 #endif
87
88 #include <linux/sysctl.h>
89
90 static const struct xlat mount_flags[] = {
91         { MS_MGC_VAL,   "MS_MGC_VAL"    },
92         { MS_RDONLY,    "MS_RDONLY"     },
93         { MS_NOSUID,    "MS_NOSUID"     },
94         { MS_NODEV,     "MS_NODEV"      },
95         { MS_NOEXEC,    "MS_NOEXEC"     },
96         { MS_SYNCHRONOUS,"MS_SYNCHRONOUS"},
97         { MS_REMOUNT,   "MS_REMOUNT"    },
98         { MS_RELATIME,  "MS_RELATIME"   },
99         { MS_KERNMOUNT, "MS_KERNMOUNT"  },
100         { MS_I_VERSION, "MS_I_VERSION"  },
101         { MS_STRICTATIME,"MS_STRICTATIME"},
102         { MS_BORN,      "MS_BORN"       },
103         { MS_MANDLOCK,  "MS_MANDLOCK"   },
104         { MS_NOATIME,   "MS_NOATIME"    },
105         { MS_NODIRATIME,"MS_NODIRATIME" },
106         { MS_BIND,      "MS_BIND"       },
107         { MS_MOVE,      "MS_MOVE"       },
108         { MS_REC,       "MS_REC"        },
109         { MS_SILENT,    "MS_SILENT"     },
110         { MS_POSIXACL,  "MS_POSIXACL"   },
111         { MS_UNBINDABLE,"MS_UNBINDABLE" },
112         { MS_PRIVATE,   "MS_PRIVATE"    },
113         { MS_SLAVE,     "MS_SLAVE"      },
114         { MS_SHARED,    "MS_SHARED"     },
115         { MS_ACTIVE,    "MS_ACTIVE"     },
116         { MS_NOUSER,    "MS_NOUSER"     },
117         { 0,            NULL            },
118 };
119
120 int
121 sys_mount(struct tcb *tcp)
122 {
123         if (entering(tcp)) {
124                 int ignore_type = 0, ignore_data = 0;
125                 unsigned long flags = tcp->u_arg[3];
126
127                 /* Discard magic */
128                 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
129                         flags &= ~MS_MGC_MSK;
130
131                 if (flags & MS_REMOUNT)
132                         ignore_type = 1;
133                 else if (flags & (MS_BIND | MS_MOVE))
134                         ignore_type = ignore_data = 1;
135
136                 printpath(tcp, tcp->u_arg[0]);
137                 tprints(", ");
138
139                 printpath(tcp, tcp->u_arg[1]);
140                 tprints(", ");
141
142                 if (ignore_type && tcp->u_arg[2])
143                         tprintf("%#lx", tcp->u_arg[2]);
144                 else
145                         printstr(tcp, tcp->u_arg[2], -1);
146                 tprints(", ");
147
148                 printflags(mount_flags, tcp->u_arg[3], "MS_???");
149                 tprints(", ");
150
151                 if (ignore_data && tcp->u_arg[4])
152                         tprintf("%#lx", tcp->u_arg[4]);
153                 else
154                         printstr(tcp, tcp->u_arg[4], -1);
155         }
156         return 0;
157 }
158
159 #define MNT_FORCE       0x00000001      /* Attempt to forcibily umount */
160 #define MNT_DETACH      0x00000002      /* Just detach from the tree */
161 #define MNT_EXPIRE      0x00000004      /* Mark for expiry */
162
163 static const struct xlat umount_flags[] = {
164         { MNT_FORCE,    "MNT_FORCE"     },
165         { MNT_DETACH,   "MNT_DETACH"    },
166         { MNT_EXPIRE,   "MNT_EXPIRE"    },
167         { 0,            NULL            },
168 };
169
170 int
171 sys_umount2(struct tcb *tcp)
172 {
173         if (entering(tcp)) {
174                 printstr(tcp, tcp->u_arg[0], -1);
175                 tprints(", ");
176                 printflags(umount_flags, tcp->u_arg[1], "MNT_???");
177         }
178         return 0;
179 }
180
181 /* These are not macros, but enums.  We just copy the values by hand
182    from Linux 2.6.9 here.  */
183 static const struct xlat personality_options[] = {
184         { 0,            "PER_LINUX"     },
185         { 0x00800000,   "PER_LINUX_32BIT"},
186         { 0x04100001,   "PER_SVR4"      },
187         { 0x05000002,   "PER_SVR3"      },
188         { 0x07000003,   "PER_SCOSVR3"   },
189         { 0x06000003,   "PER_OSR5"      },
190         { 0x05000004,   "PER_WYSEV386"  },
191         { 0x04000005,   "PER_ISCR4"     },
192         { 0x00000006,   "PER_BSD"       },
193         { 0x04000006,   "PER_SUNOS"     },
194         { 0x05000007,   "PER_XENIX"     },
195         { 0x00000008,   "PER_LINUX32"   },
196         { 0x08000008,   "PER_LINUX32_3GB"},
197         { 0x04000009,   "PER_IRIX32"    },
198         { 0x0400000a,   "PER_IRIXN32"   },
199         { 0x0400000b,   "PER_IRIX64"    },
200         { 0x0000000c,   "PER_RISCOS"    },
201         { 0x0400000d,   "PER_SOLARIS"   },
202         { 0x0410000e,   "PER_UW7"       },
203         { 0x0000000f,   "PER_OSF4"      },
204         { 0x00000010,   "PER_HPUX"      },
205         { 0,            NULL            },
206 };
207
208 int
209 sys_personality(struct tcb *tcp)
210 {
211         if (entering(tcp))
212                 printxval(personality_options, tcp->u_arg[0], "PER_???");
213         return 0;
214 }
215
216 enum {
217         SYSLOG_ACTION_CLOSE = 0,
218         SYSLOG_ACTION_OPEN,
219         SYSLOG_ACTION_READ,
220         SYSLOG_ACTION_READ_ALL,
221         SYSLOG_ACTION_READ_CLEAR,
222         SYSLOG_ACTION_CLEAR,
223         SYSLOG_ACTION_CONSOLE_OFF,
224         SYSLOG_ACTION_CONSOLE_ON,
225         SYSLOG_ACTION_CONSOLE_LEVEL,
226         SYSLOG_ACTION_SIZE_UNREAD,
227         SYSLOG_ACTION_SIZE_BUFFER
228 };
229
230 static const struct xlat syslog_action_type[] = {
231         { SYSLOG_ACTION_CLOSE,          "SYSLOG_ACTION_CLOSE"           },
232         { SYSLOG_ACTION_OPEN,           "SYSLOG_ACTION_OPEN"            },
233         { SYSLOG_ACTION_READ,           "SYSLOG_ACTION_READ"            },
234         { SYSLOG_ACTION_READ_ALL,       "SYSLOG_ACTION_READ_ALL"        },
235         { SYSLOG_ACTION_READ_CLEAR,     "SYSLOG_ACTION_READ_CLEAR"      },
236         { SYSLOG_ACTION_CLEAR,          "SYSLOG_ACTION_CLEAR"           },
237         { SYSLOG_ACTION_CONSOLE_OFF,    "SYSLOG_ACTION_CONSOLE_OFF"     },
238         { SYSLOG_ACTION_CONSOLE_ON,     "SYSLOG_ACTION_CONSOLE_ON"      },
239         { SYSLOG_ACTION_CONSOLE_LEVEL,  "SYSLOG_ACTION_CONSOLE_LEVEL"   },
240         { SYSLOG_ACTION_SIZE_UNREAD,    "SYSLOG_ACTION_SIZE_UNREAD"     },
241         { SYSLOG_ACTION_SIZE_BUFFER,    "SYSLOG_ACTION_SIZE_BUFFER"     },
242         { 0,                            NULL                            }
243 };
244
245 int
246 sys_syslog(struct tcb *tcp)
247 {
248         int type = tcp->u_arg[0];
249
250         if (entering(tcp)) {
251                 /* type */
252                 printxval(syslog_action_type, type, "SYSLOG_ACTION_???");
253                 tprints(", ");
254         }
255
256         switch (type) {
257                 case SYSLOG_ACTION_READ:
258                 case SYSLOG_ACTION_READ_ALL:
259                 case SYSLOG_ACTION_READ_CLEAR:
260                         if (entering(tcp))
261                                 return 0;
262                         break;
263                 default:
264                         if (entering(tcp)) {
265                                 tprintf("%#lx, %lu",
266                                         tcp->u_arg[1], tcp->u_arg[2]);
267                         }
268                         return 0;
269         }
270
271         /* bufp */
272         if (syserror(tcp))
273                 tprintf("%#lx", tcp->u_arg[1]);
274         else
275                 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
276         /* len */
277         tprintf(", %d", (int) tcp->u_arg[2]);
278
279         return 0;
280 }
281
282 #include <linux/reboot.h>
283 static const struct xlat bootflags1[] = {
284         { LINUX_REBOOT_MAGIC1,  "LINUX_REBOOT_MAGIC1"   },
285         { 0,                    NULL                    },
286 };
287
288 static const struct xlat bootflags2[] = {
289         { LINUX_REBOOT_MAGIC2,  "LINUX_REBOOT_MAGIC2"   },
290         { LINUX_REBOOT_MAGIC2A, "LINUX_REBOOT_MAGIC2A"  },
291         { LINUX_REBOOT_MAGIC2B, "LINUX_REBOOT_MAGIC2B"  },
292         { 0,                    NULL                    },
293 };
294
295 static const struct xlat bootflags3[] = {
296         { LINUX_REBOOT_CMD_CAD_OFF,     "LINUX_REBOOT_CMD_CAD_OFF"      },
297         { LINUX_REBOOT_CMD_RESTART,     "LINUX_REBOOT_CMD_RESTART"      },
298         { LINUX_REBOOT_CMD_HALT,        "LINUX_REBOOT_CMD_HALT"         },
299         { LINUX_REBOOT_CMD_CAD_ON,      "LINUX_REBOOT_CMD_CAD_ON"       },
300         { LINUX_REBOOT_CMD_POWER_OFF,   "LINUX_REBOOT_CMD_POWER_OFF"    },
301         { LINUX_REBOOT_CMD_RESTART2,    "LINUX_REBOOT_CMD_RESTART2"     },
302         { 0,                            NULL                            },
303 };
304
305 int
306 sys_reboot(struct tcb *tcp)
307 {
308         if (entering(tcp)) {
309                 printflags(bootflags1, tcp->u_arg[0], "LINUX_REBOOT_MAGIC_???");
310                 tprints(", ");
311                 printflags(bootflags2, tcp->u_arg[1], "LINUX_REBOOT_MAGIC_???");
312                 tprints(", ");
313                 printflags(bootflags3, tcp->u_arg[2], "LINUX_REBOOT_CMD_???");
314                 if (tcp->u_arg[2] == LINUX_REBOOT_CMD_RESTART2) {
315                         tprints(", ");
316                         printstr(tcp, tcp->u_arg[3], -1);
317                 }
318         }
319         return 0;
320 }
321
322 #ifdef M68K
323 static const struct xlat cacheflush_scope[] = {
324 #ifdef FLUSH_SCOPE_LINE
325         { FLUSH_SCOPE_LINE,     "FLUSH_SCOPE_LINE" },
326 #endif
327 #ifdef FLUSH_SCOPE_PAGE
328         { FLUSH_SCOPE_PAGE,     "FLUSH_SCOPE_PAGE" },
329 #endif
330 #ifdef FLUSH_SCOPE_ALL
331         { FLUSH_SCOPE_ALL,      "FLUSH_SCOPE_ALL" },
332 #endif
333         { 0,                    NULL },
334 };
335
336 static const struct xlat cacheflush_flags[] = {
337 #ifdef FLUSH_CACHE_BOTH
338         { FLUSH_CACHE_BOTH,     "FLUSH_CACHE_BOTH" },
339 #endif
340 #ifdef FLUSH_CACHE_DATA
341         { FLUSH_CACHE_DATA,     "FLUSH_CACHE_DATA" },
342 #endif
343 #ifdef FLUSH_CACHE_INSN
344         { FLUSH_CACHE_INSN,     "FLUSH_CACHE_INSN" },
345 #endif
346         { 0,                    NULL },
347 };
348
349 int
350 sys_cacheflush(struct tcb *tcp)
351 {
352         if (entering(tcp)) {
353                 /* addr */
354                 tprintf("%#lx, ", tcp->u_arg[0]);
355                 /* scope */
356                 printxval(cacheflush_scope, tcp->u_arg[1], "FLUSH_SCOPE_???");
357                 tprints(", ");
358                 /* flags */
359                 printflags(cacheflush_flags, tcp->u_arg[2], "FLUSH_CACHE_???");
360                 /* len */
361                 tprintf(", %lu", tcp->u_arg[3]);
362         }
363         return 0;
364 }
365 #endif /* M68K */
366
367 #ifdef BFIN
368
369 #include <bfin_sram.h>
370
371 static const struct xlat sram_alloc_flags[] = {
372         { L1_INST_SRAM,         "L1_INST_SRAM" },
373         { L1_DATA_A_SRAM,       "L1_DATA_A_SRAM" },
374         { L1_DATA_B_SRAM,       "L1_DATA_B_SRAM" },
375         { L1_DATA_SRAM,         "L1_DATA_SRAM" },
376         { L2_SRAM,              "L2_SRAM" },
377         { 0,                    NULL },
378 };
379
380 int
381 sys_sram_alloc(struct tcb *tcp)
382 {
383         if (entering(tcp)) {
384                 /* size */
385                 tprintf("%lu, ", tcp->u_arg[0]);
386                 /* flags */
387                 printxval(sram_alloc_flags, tcp->u_arg[1], "???_SRAM");
388         }
389         return 1;
390 }
391
392 #include <asm/cachectl.h>
393
394 static const struct xlat cacheflush_flags[] = {
395         { ICACHE,       "ICACHE" },
396         { DCACHE,       "DCACHE" },
397         { BCACHE,       "BCACHE" },
398         { 0,            NULL },
399 };
400
401 int
402 sys_cacheflush(struct tcb *tcp)
403 {
404         if (entering(tcp)) {
405                 /* start addr */
406                 tprintf("%#lx, ", tcp->u_arg[0]);
407                 /* length */
408                 tprintf("%ld, ", tcp->u_arg[1]);
409                 /* flags */
410                 printxval(cacheflush_flags, tcp->u_arg[1], "?CACHE");
411         }
412         return 0;
413 }
414
415 #endif
416
417 #ifdef SH
418 static const struct xlat cacheflush_flags[] = {
419 #ifdef CACHEFLUSH_D_INVAL
420         { CACHEFLUSH_D_INVAL,   "CACHEFLUSH_D_INVAL" },
421 #endif
422 #ifdef CACHEFLUSH_D_WB
423         { CACHEFLUSH_D_WB,      "CACHEFLUSH_D_WB" },
424 #endif
425 #ifdef CACHEFLUSH_D_PURGE
426         { CACHEFLUSH_D_PURGE,   "CACHEFLUSH_D_PURGE" },
427 #endif
428 #ifdef CACHEFLUSH_I
429         { CACHEFLUSH_I,         "CACHEFLUSH_I" },
430 #endif
431         { 0,                    NULL },
432 };
433
434 int
435 sys_cacheflush(struct tcb *tcp)
436 {
437         if (entering(tcp)) {
438                 /* addr */
439                 tprintf("%#lx, ", tcp->u_arg[0]);
440                 /* len */
441                 tprintf("%lu, ", tcp->u_arg[1]);
442                 /* flags */
443                 printflags(cacheflush_flags, tcp->u_arg[2], "CACHEFLUSH_???");
444         }
445         return 0;
446 }
447 #endif /* SH */
448
449 #ifdef SYS_capget
450
451 static const struct xlat capabilities[] = {
452         { 1<<CAP_CHOWN,         "CAP_CHOWN"     },
453         { 1<<CAP_DAC_OVERRIDE,  "CAP_DAC_OVERRIDE"},
454         { 1<<CAP_DAC_READ_SEARCH,"CAP_DAC_READ_SEARCH"},
455         { 1<<CAP_FOWNER,        "CAP_FOWNER"    },
456         { 1<<CAP_FSETID,        "CAP_FSETID"    },
457         { 1<<CAP_KILL,          "CAP_KILL"      },
458         { 1<<CAP_SETGID,        "CAP_SETGID"    },
459         { 1<<CAP_SETUID,        "CAP_SETUID"    },
460         { 1<<CAP_SETPCAP,       "CAP_SETPCAP"   },
461         { 1<<CAP_LINUX_IMMUTABLE,"CAP_LINUX_IMMUTABLE"},
462         { 1<<CAP_NET_BIND_SERVICE,"CAP_NET_BIND_SERVICE"},
463         { 1<<CAP_NET_BROADCAST, "CAP_NET_BROADCAST"},
464         { 1<<CAP_NET_ADMIN,     "CAP_NET_ADMIN" },
465         { 1<<CAP_NET_RAW,       "CAP_NET_RAW"   },
466         { 1<<CAP_IPC_LOCK,      "CAP_IPC_LOCK"  },
467         { 1<<CAP_IPC_OWNER,     "CAP_IPC_OWNER" },
468         { 1<<CAP_SYS_MODULE,    "CAP_SYS_MODULE"},
469         { 1<<CAP_SYS_RAWIO,     "CAP_SYS_RAWIO" },
470         { 1<<CAP_SYS_CHROOT,    "CAP_SYS_CHROOT"},
471         { 1<<CAP_SYS_PTRACE,    "CAP_SYS_PTRACE"},
472         { 1<<CAP_SYS_PACCT,     "CAP_SYS_PACCT" },
473         { 1<<CAP_SYS_ADMIN,     "CAP_SYS_ADMIN" },
474         { 1<<CAP_SYS_BOOT,      "CAP_SYS_BOOT"  },
475         { 1<<CAP_SYS_NICE,      "CAP_SYS_NICE"  },
476         { 1<<CAP_SYS_RESOURCE,  "CAP_SYS_RESOURCE"},
477         { 1<<CAP_SYS_TIME,      "CAP_SYS_TIME"  },
478         { 1<<CAP_SYS_TTY_CONFIG,"CAP_SYS_TTY_CONFIG"},
479 #ifdef CAP_MKNOD
480         { 1<<CAP_MKNOD,         "CAP_MKNOD"     },
481 #endif
482 #ifdef CAP_LEASE
483         { 1<<CAP_LEASE,         "CAP_LEASE"     },
484 #endif
485 #ifdef CAP_AUDIT_WRITE
486         { 1<<CAP_AUDIT_WRITE,   "CAP_AUDIT_WRITE"},
487 #endif
488 #ifdef CAP_AUDIT_CONTROL
489         { 1<<CAP_AUDIT_CONTROL, "CAP_AUDIT_CONTROL"},
490 #endif
491 #ifdef CAP_SETFCAP
492         { 1<<CAP_SETFCAP,       "CAP_SETFCAP"   },
493 #endif
494         { 0,            NULL            },
495 };
496
497 int
498 sys_capget(struct tcb *tcp)
499 {
500         /* cap_user_ types are _pointers_ to (small) structs. */
501         /* Structs themselves have no names defined. */
502         /* Have to use ugly hack to place them on stack. */
503         union { cap_user_header_t p; long *a; char *c; } arg0;
504         union { cap_user_data_t p; long *a; char *c; } arg1;
505         long a0[sizeof(*arg0.p) / sizeof(long) + 1];
506         long a1[sizeof(*arg1.p) / sizeof(long) + 1];
507         arg0.a = a0;
508         arg1.a = a1;
509
510         if (!entering(tcp)) {
511                 if (!tcp->u_arg[0])
512                         tprints("NULL");
513                 else if (!verbose(tcp))
514                         tprintf("%#lx", tcp->u_arg[0]);
515                 else if (umoven(tcp, tcp->u_arg[0], sizeof(*arg0.p), arg0.c) < 0)
516                         tprints("???");
517                 else {
518                         tprintf("%#x, %d", arg0.p->version, arg0.p->pid);
519                 }
520                 tprints(", ");
521                 if (!tcp->u_arg[1])
522                         tprints("NULL");
523                 else if (!verbose(tcp))
524                         tprintf("%#lx", tcp->u_arg[1]);
525                 else if (umoven(tcp, tcp->u_arg[1], sizeof(*arg1.p), arg1.c) < 0)
526                         tprints("???");
527                 else {
528                         tprints("{");
529                         printflags(capabilities, arg1.p->effective, "CAP_???");
530                         tprints(", ");
531                         printflags(capabilities, arg1.p->permitted, "CAP_???");
532                         tprints(", ");
533                         printflags(capabilities, arg1.p->inheritable, "CAP_???");
534                         tprints("}");
535                 }
536         }
537         return 0;
538 }
539
540 int
541 sys_capset(struct tcb *tcp)
542 {
543         union { cap_user_header_t p; long *a; char *c; } arg0;
544         union { cap_user_data_t p; long *a; char *c; } arg1;
545         long a0[sizeof(*arg0.p) / sizeof(long) + 1];
546         long a1[sizeof(*arg1.p) / sizeof(long) + 1];
547         arg0.a = a0;
548         arg1.a = a1;
549
550         if (entering(tcp)) {
551                 if (!tcp->u_arg[0])
552                         tprints("NULL");
553                 else if (!verbose(tcp))
554                         tprintf("%#lx", tcp->u_arg[0]);
555                 else if (umoven(tcp, tcp->u_arg[0], sizeof(*arg0.p), arg0.c) < 0)
556                         tprints("???");
557                 else {
558                         tprintf("%#x, %d", arg0.p->version, arg0.p->pid);
559                 }
560                 tprints(", ");
561                 if (!tcp->u_arg[1])
562                         tprints("NULL");
563                 else if (!verbose(tcp))
564                         tprintf("%#lx", tcp->u_arg[1]);
565                 else if (umoven(tcp, tcp->u_arg[1], sizeof(*arg1.p), arg1.c) < 0)
566                         tprints("???");
567                 else {
568                         tprints("{");
569                         printflags(capabilities, arg1.p->effective, "CAP_???");
570                         tprints(", ");
571                         printflags(capabilities, arg1.p->permitted, "CAP_???");
572                         tprints(", ");
573                         printflags(capabilities, arg1.p->inheritable, "CAP_???");
574                         tprints("}");
575                 }
576         }
577         return 0;
578 }
579
580 #else
581
582 int sys_capget(struct tcb *tcp)
583 {
584         return printargs(tcp);
585 }
586
587 int sys_capset(struct tcb *tcp)
588 {
589         return printargs(tcp);
590 }
591
592 #endif
593
594 /* Linux 2.6.18+ headers removed CTL_PROC enum.  */
595 # define CTL_PROC 4
596 # define CTL_CPU 10             /* older headers lack */
597 static const struct xlat sysctl_root[] = {
598         { CTL_KERN, "CTL_KERN" },
599         { CTL_VM, "CTL_VM" },
600         { CTL_NET, "CTL_NET" },
601         { CTL_PROC, "CTL_PROC" },
602         { CTL_FS, "CTL_FS" },
603         { CTL_DEBUG, "CTL_DEBUG" },
604         { CTL_DEV, "CTL_DEV" },
605         { CTL_BUS, "CTL_BUS" },
606         { CTL_ABI, "CTL_ABI" },
607         { CTL_CPU, "CTL_CPU" },
608         { 0, NULL }
609 };
610
611 static const struct xlat sysctl_kern[] = {
612         { KERN_OSTYPE, "KERN_OSTYPE" },
613         { KERN_OSRELEASE, "KERN_OSRELEASE" },
614         { KERN_OSREV, "KERN_OSREV" },
615         { KERN_VERSION, "KERN_VERSION" },
616         { KERN_SECUREMASK, "KERN_SECUREMASK" },
617         { KERN_PROF, "KERN_PROF" },
618         { KERN_NODENAME, "KERN_NODENAME" },
619         { KERN_DOMAINNAME, "KERN_DOMAINNAME" },
620 #ifdef KERN_SECURELVL
621         { KERN_SECURELVL, "KERN_SECURELVL" },
622 #endif
623         { KERN_PANIC, "KERN_PANIC" },
624 #ifdef KERN_REALROOTDEV
625         { KERN_REALROOTDEV, "KERN_REALROOTDEV" },
626 #endif
627 #ifdef KERN_JAVA_INTERPRETER
628         { KERN_JAVA_INTERPRETER, "KERN_JAVA_INTERPRETER" },
629 #endif
630 #ifdef KERN_JAVA_APPLETVIEWER
631         { KERN_JAVA_APPLETVIEWER, "KERN_JAVA_APPLETVIEWER" },
632 #endif
633         { KERN_SPARC_REBOOT, "KERN_SPARC_REBOOT" },
634         { KERN_CTLALTDEL, "KERN_CTLALTDEL" },
635         { KERN_PRINTK, "KERN_PRINTK" },
636         { KERN_NAMETRANS, "KERN_NAMETRANS" },
637         { KERN_PPC_HTABRECLAIM, "KERN_PPC_HTABRECLAIM" },
638         { KERN_PPC_ZEROPAGED, "KERN_PPC_ZEROPAGED" },
639         { KERN_PPC_POWERSAVE_NAP, "KERN_PPC_POWERSAVE_NAP" },
640         { KERN_MODPROBE, "KERN_MODPROBE" },
641         { KERN_SG_BIG_BUFF, "KERN_SG_BIG_BUFF" },
642         { KERN_ACCT, "KERN_ACCT" },
643         { KERN_PPC_L2CR, "KERN_PPC_L2CR" },
644         { KERN_RTSIGNR, "KERN_RTSIGNR" },
645         { KERN_RTSIGMAX, "KERN_RTSIGMAX" },
646         { KERN_SHMMAX, "KERN_SHMMAX" },
647         { KERN_MSGMAX, "KERN_MSGMAX" },
648         { KERN_MSGMNB, "KERN_MSGMNB" },
649         { KERN_MSGPOOL, "KERN_MSGPOOL" },
650         { 0, NULL }
651 };
652
653 static const struct xlat sysctl_vm[] = {
654 #ifdef VM_SWAPCTL
655         { VM_SWAPCTL, "VM_SWAPCTL" },
656 #endif
657 #ifdef VM_UNUSED1
658         { VM_UNUSED1, "VM_UNUSED1" },
659 #endif
660 #ifdef VM_SWAPOUT
661         { VM_SWAPOUT, "VM_SWAPOUT" },
662 #endif
663 #ifdef VM_UNUSED2
664         { VM_UNUSED2, "VM_UNUSED2" },
665 #endif
666 #ifdef VM_FREEPG
667         { VM_FREEPG, "VM_FREEPG" },
668 #endif
669 #ifdef VM_UNUSED3
670         { VM_UNUSED3, "VM_UNUSED3" },
671 #endif
672 #ifdef VM_BDFLUSH
673         { VM_BDFLUSH, "VM_BDFLUSH" },
674 #endif
675 #ifdef VM_UNUSED4
676         { VM_UNUSED4, "VM_UNUSED4" },
677 #endif
678         { VM_OVERCOMMIT_MEMORY, "VM_OVERCOMMIT_MEMORY" },
679 #ifdef VM_BUFFERMEM
680         { VM_BUFFERMEM, "VM_BUFFERMEM" },
681 #endif
682 #ifdef VM_UNUSED5
683         { VM_UNUSED5, "VM_UNUSED5" },
684 #endif
685 #ifdef VM_PAGECACHE
686         { VM_PAGECACHE, "VM_PAGECACHE" },
687 #endif
688 #ifdef VM_UNUSED7
689         { VM_UNUSED7, "VM_UNUSED7" },
690 #endif
691 #ifdef VM_PAGERDAEMON
692         { VM_PAGERDAEMON, "VM_PAGERDAEMON" },
693 #endif
694 #ifdef VM_UNUSED8
695         { VM_UNUSED8, "VM_UNUSED8" },
696 #endif
697 #ifdef VM_PGT_CACHE
698         { VM_PGT_CACHE, "VM_PGT_CACHE" },
699 #endif
700 #ifdef VM_UNUSED9
701         { VM_UNUSED9, "VM_UNUSED9" },
702 #endif
703         { VM_PAGE_CLUSTER, "VM_PAGE_CLUSTER" },
704         { 0, NULL },
705 };
706
707 static const struct xlat sysctl_net[] = {
708         { NET_CORE, "NET_CORE" },
709         { NET_ETHER, "NET_ETHER" },
710         { NET_802, "NET_802" },
711         { NET_UNIX, "NET_UNIX" },
712         { NET_IPV4, "NET_IPV4" },
713         { NET_IPX, "NET_IPX" },
714         { NET_ATALK, "NET_ATALK" },
715         { NET_NETROM, "NET_NETROM" },
716         { NET_AX25, "NET_AX25" },
717         { NET_BRIDGE, "NET_BRIDGE" },
718         { NET_ROSE, "NET_ROSE" },
719         { NET_IPV6, "NET_IPV6" },
720         { NET_X25, "NET_X25" },
721         { NET_TR, "NET_TR" },
722         { NET_DECNET, "NET_DECNET" },
723         { 0, NULL }
724 };
725
726 static const struct xlat sysctl_net_core[] = {
727         { NET_CORE_WMEM_MAX, "NET_CORE_WMEM_MAX" },
728         { NET_CORE_RMEM_MAX, "NET_CORE_RMEM_MAX" },
729         { NET_CORE_WMEM_DEFAULT, "NET_CORE_WMEM_DEFAULT" },
730         { NET_CORE_RMEM_DEFAULT, "NET_CORE_RMEM_DEFAULT" },
731         { NET_CORE_MAX_BACKLOG, "NET_CORE_MAX_BACKLOG" },
732         { NET_CORE_FASTROUTE, "NET_CORE_FASTROUTE" },
733         { NET_CORE_MSG_COST, "NET_CORE_MSG_COST" },
734         { NET_CORE_MSG_BURST, "NET_CORE_MSG_BURST" },
735         { NET_CORE_OPTMEM_MAX, "NET_CORE_OPTMEM_MAX" },
736         { 0, NULL }
737 };
738
739 static const struct xlat sysctl_net_unix[] = {
740         { NET_UNIX_DESTROY_DELAY, "NET_UNIX_DESTROY_DELAY" },
741         { NET_UNIX_DELETE_DELAY, "NET_UNIX_DELETE_DELAY" },
742         { 0, NULL }
743 };
744
745 static const struct xlat sysctl_net_ipv4[] = {
746         { NET_IPV4_FORWARD, "NET_IPV4_FORWARD" },
747         { NET_IPV4_DYNADDR, "NET_IPV4_DYNADDR" },
748         { NET_IPV4_CONF, "NET_IPV4_CONF" },
749         { NET_IPV4_NEIGH, "NET_IPV4_NEIGH" },
750         { NET_IPV4_ROUTE, "NET_IPV4_ROUTE" },
751         { NET_IPV4_FIB_HASH, "NET_IPV4_FIB_HASH" },
752         { NET_IPV4_TCP_TIMESTAMPS, "NET_IPV4_TCP_TIMESTAMPS" },
753         { NET_IPV4_TCP_WINDOW_SCALING, "NET_IPV4_TCP_WINDOW_SCALING" },
754         { NET_IPV4_TCP_SACK, "NET_IPV4_TCP_SACK" },
755         { NET_IPV4_TCP_RETRANS_COLLAPSE, "NET_IPV4_TCP_RETRANS_COLLAPSE" },
756         { NET_IPV4_DEFAULT_TTL, "NET_IPV4_DEFAULT_TTL" },
757         { NET_IPV4_AUTOCONFIG, "NET_IPV4_AUTOCONFIG" },
758         { NET_IPV4_NO_PMTU_DISC, "NET_IPV4_NO_PMTU_DISC" },
759         { NET_IPV4_TCP_SYN_RETRIES, "NET_IPV4_TCP_SYN_RETRIES" },
760         { NET_IPV4_IPFRAG_HIGH_THRESH, "NET_IPV4_IPFRAG_HIGH_THRESH" },
761         { NET_IPV4_IPFRAG_LOW_THRESH, "NET_IPV4_IPFRAG_LOW_THRESH" },
762         { NET_IPV4_IPFRAG_TIME, "NET_IPV4_IPFRAG_TIME" },
763         { NET_IPV4_TCP_MAX_KA_PROBES, "NET_IPV4_TCP_MAX_KA_PROBES" },
764         { NET_IPV4_TCP_KEEPALIVE_TIME, "NET_IPV4_TCP_KEEPALIVE_TIME" },
765         { NET_IPV4_TCP_KEEPALIVE_PROBES, "NET_IPV4_TCP_KEEPALIVE_PROBES" },
766         { NET_IPV4_TCP_RETRIES1, "NET_IPV4_TCP_RETRIES1" },
767         { NET_IPV4_TCP_RETRIES2, "NET_IPV4_TCP_RETRIES2" },
768         { NET_IPV4_TCP_FIN_TIMEOUT, "NET_IPV4_TCP_FIN_TIMEOUT" },
769         { NET_IPV4_IP_MASQ_DEBUG, "NET_IPV4_IP_MASQ_DEBUG" },
770         { NET_TCP_SYNCOOKIES, "NET_TCP_SYNCOOKIES" },
771         { NET_TCP_STDURG, "NET_TCP_STDURG" },
772         { NET_TCP_RFC1337, "NET_TCP_RFC1337" },
773         { NET_TCP_SYN_TAILDROP, "NET_TCP_SYN_TAILDROP" },
774         { NET_TCP_MAX_SYN_BACKLOG, "NET_TCP_MAX_SYN_BACKLOG" },
775         { NET_IPV4_LOCAL_PORT_RANGE, "NET_IPV4_LOCAL_PORT_RANGE" },
776         { NET_IPV4_ICMP_ECHO_IGNORE_ALL, "NET_IPV4_ICMP_ECHO_IGNORE_ALL" },
777         { NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS, "NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS" },
778         { NET_IPV4_ICMP_SOURCEQUENCH_RATE, "NET_IPV4_ICMP_SOURCEQUENCH_RATE" },
779         { NET_IPV4_ICMP_DESTUNREACH_RATE, "NET_IPV4_ICMP_DESTUNREACH_RATE" },
780         { NET_IPV4_ICMP_TIMEEXCEED_RATE, "NET_IPV4_ICMP_TIMEEXCEED_RATE" },
781         { NET_IPV4_ICMP_PARAMPROB_RATE, "NET_IPV4_ICMP_PARAMPROB_RATE" },
782         { NET_IPV4_ICMP_ECHOREPLY_RATE, "NET_IPV4_ICMP_ECHOREPLY_RATE" },
783         { NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES, "NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES" },
784         { NET_IPV4_IGMP_MAX_MEMBERSHIPS, "NET_IPV4_IGMP_MAX_MEMBERSHIPS" },
785         {  0, NULL }
786 };
787
788 static const struct xlat sysctl_net_ipv4_route[] = {
789         { NET_IPV4_ROUTE_FLUSH, "NET_IPV4_ROUTE_FLUSH" },
790         { NET_IPV4_ROUTE_MIN_DELAY, "NET_IPV4_ROUTE_MIN_DELAY" },
791         { NET_IPV4_ROUTE_MAX_DELAY, "NET_IPV4_ROUTE_MAX_DELAY" },
792         { NET_IPV4_ROUTE_GC_THRESH, "NET_IPV4_ROUTE_GC_THRESH" },
793         { NET_IPV4_ROUTE_MAX_SIZE, "NET_IPV4_ROUTE_MAX_SIZE" },
794         { NET_IPV4_ROUTE_GC_MIN_INTERVAL, "NET_IPV4_ROUTE_GC_MIN_INTERVAL" },
795         { NET_IPV4_ROUTE_GC_TIMEOUT, "NET_IPV4_ROUTE_GC_TIMEOUT" },
796         { NET_IPV4_ROUTE_GC_INTERVAL, "NET_IPV4_ROUTE_GC_INTERVAL" },
797         { NET_IPV4_ROUTE_REDIRECT_LOAD, "NET_IPV4_ROUTE_REDIRECT_LOAD" },
798         { NET_IPV4_ROUTE_REDIRECT_NUMBER, "NET_IPV4_ROUTE_REDIRECT_NUMBER" },
799         { NET_IPV4_ROUTE_REDIRECT_SILENCE, "NET_IPV4_ROUTE_REDIRECT_SILENCE" },
800         { NET_IPV4_ROUTE_ERROR_COST, "NET_IPV4_ROUTE_ERROR_COST" },
801         { NET_IPV4_ROUTE_ERROR_BURST, "NET_IPV4_ROUTE_ERROR_BURST" },
802         { NET_IPV4_ROUTE_GC_ELASTICITY, "NET_IPV4_ROUTE_GC_ELASTICITY" },
803         { 0, NULL }
804 };
805
806 static const struct xlat sysctl_net_ipv4_conf[] = {
807         { NET_IPV4_CONF_FORWARDING, "NET_IPV4_CONF_FORWARDING" },
808         { NET_IPV4_CONF_MC_FORWARDING, "NET_IPV4_CONF_MC_FORWARDING" },
809         { NET_IPV4_CONF_PROXY_ARP, "NET_IPV4_CONF_PROXY_ARP" },
810         { NET_IPV4_CONF_ACCEPT_REDIRECTS, "NET_IPV4_CONF_ACCEPT_REDIRECTS" },
811         { NET_IPV4_CONF_SECURE_REDIRECTS, "NET_IPV4_CONF_SECURE_REDIRECTS" },
812         { NET_IPV4_CONF_SEND_REDIRECTS, "NET_IPV4_CONF_SEND_REDIRECTS" },
813         { NET_IPV4_CONF_SHARED_MEDIA, "NET_IPV4_CONF_SHARED_MEDIA" },
814         { NET_IPV4_CONF_RP_FILTER, "NET_IPV4_CONF_RP_FILTER" },
815         { NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE, "NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE" },
816         { NET_IPV4_CONF_BOOTP_RELAY, "NET_IPV4_CONF_BOOTP_RELAY" },
817         { NET_IPV4_CONF_LOG_MARTIANS, "NET_IPV4_CONF_LOG_MARTIANS" },
818         { 0, NULL }
819 };
820
821 static const struct xlat sysctl_net_ipv6[] = {
822         { NET_IPV6_CONF, "NET_IPV6_CONF" },
823         { NET_IPV6_NEIGH, "NET_IPV6_NEIGH" },
824         { NET_IPV6_ROUTE, "NET_IPV6_ROUTE" },
825         { 0, NULL }
826 };
827
828 static const struct xlat sysctl_net_ipv6_route[] = {
829         { NET_IPV6_ROUTE_FLUSH, "NET_IPV6_ROUTE_FLUSH" },
830         { NET_IPV6_ROUTE_GC_THRESH, "NET_IPV6_ROUTE_GC_THRESH" },
831         { NET_IPV6_ROUTE_MAX_SIZE, "NET_IPV6_ROUTE_MAX_SIZE" },
832         { NET_IPV6_ROUTE_GC_MIN_INTERVAL, "NET_IPV6_ROUTE_GC_MIN_INTERVAL" },
833         { NET_IPV6_ROUTE_GC_TIMEOUT, "NET_IPV6_ROUTE_GC_TIMEOUT" },
834         { NET_IPV6_ROUTE_GC_INTERVAL, "NET_IPV6_ROUTE_GC_INTERVAL" },
835         { NET_IPV6_ROUTE_GC_ELASTICITY, "NET_IPV6_ROUTE_GC_ELASTICITY" },
836         { 0, NULL }
837 };
838
839 int
840 sys_sysctl(struct tcb *tcp)
841 {
842         struct __sysctl_args info;
843         int *name;
844         unsigned long size;
845
846         if (umove(tcp, tcp->u_arg[0], &info) < 0)
847                 return printargs(tcp);
848
849         size = sizeof(int) * (unsigned long) info.nlen;
850         name = (size / sizeof(int) != info.nlen) ? NULL : malloc(size);
851         if (name == NULL ||
852             umoven(tcp, (unsigned long) info.name, size, (char *) name) < 0) {
853                 free(name);
854                 if (entering(tcp))
855                         tprintf("{%p, %d, %p, %p, %p, %Zu}",
856                                 info.name, info.nlen, info.oldval,
857                                 info.oldlenp, info.newval, info.newlen);
858                 return 0;
859         }
860
861         if (entering(tcp)) {
862                 int cnt = 0, max_cnt;
863
864                 tprints("{{");
865
866                 if (info.nlen == 0)
867                         goto out;
868                 printxval(sysctl_root, name[0], "CTL_???");
869                 ++cnt;
870
871                 if (info.nlen == 1)
872                         goto out;
873                 switch (name[0]) {
874                 case CTL_KERN:
875                         tprints(", ");
876                         printxval(sysctl_kern, name[1], "KERN_???");
877                         ++cnt;
878                         break;
879                 case CTL_VM:
880                         tprints(", ");
881                         printxval(sysctl_vm, name[1], "VM_???");
882                         ++cnt;
883                         break;
884                 case CTL_NET:
885                         tprints(", ");
886                         printxval(sysctl_net, name[1], "NET_???");
887                         ++cnt;
888
889                         if (info.nlen == 2)
890                                 goto out;
891                         switch (name[1]) {
892                         case NET_CORE:
893                                 tprints(", ");
894                                 printxval(sysctl_net_core, name[2],
895                                           "NET_CORE_???");
896                                 break;
897                         case NET_UNIX:
898                                 tprints(", ");
899                                 printxval(sysctl_net_unix, name[2],
900                                           "NET_UNIX_???");
901                                 break;
902                         case NET_IPV4:
903                                 tprints(", ");
904                                 printxval(sysctl_net_ipv4, name[2],
905                                           "NET_IPV4_???");
906
907                                 if (info.nlen == 3)
908                                         goto out;
909                                 switch (name[2]) {
910                                 case NET_IPV4_ROUTE:
911                                         tprints(", ");
912                                         printxval(sysctl_net_ipv4_route,
913                                                   name[3],
914                                                   "NET_IPV4_ROUTE_???");
915                                         break;
916                                 case NET_IPV4_CONF:
917                                         tprints(", ");
918                                         printxval(sysctl_net_ipv4_conf,
919                                                   name[3],
920                                                   "NET_IPV4_CONF_???");
921                                         break;
922                                 default:
923                                         goto out;
924                                 }
925                                 break;
926                         case NET_IPV6:
927                                 tprints(", ");
928                                 printxval(sysctl_net_ipv6, name[2],
929                                           "NET_IPV6_???");
930
931                                 if (info.nlen == 3)
932                                         goto out;
933                                 switch (name[2]) {
934                                 case NET_IPV6_ROUTE:
935                                         tprints(", ");
936                                         printxval(sysctl_net_ipv6_route,
937                                                   name[3],
938                                                   "NET_IPV6_ROUTE_???");
939                                         break;
940                                 default:
941                                         goto out;
942                                 }
943                                 break;
944                         default:
945                                 goto out;
946                         }
947                         break;
948                 default:
949                         goto out;
950                 }
951         out:
952                 max_cnt = info.nlen;
953                 if (abbrev(tcp) && max_cnt > max_strlen)
954                         max_cnt = max_strlen;
955                 while (cnt < max_cnt)
956                         tprintf(", %x", name[cnt++]);
957                 if (cnt < info.nlen)
958                         tprints(", ...");
959                 tprintf("}, %d, ", info.nlen);
960         } else {
961                 size_t oldlen;
962                 if (umove(tcp, (size_t)info.oldlenp, &oldlen) >= 0
963                     && info.nlen >= 2
964                     && ((name[0] == CTL_KERN
965                          && (name[1] == KERN_OSRELEASE
966                              || name[1] == KERN_OSTYPE
967 #ifdef KERN_JAVA_INTERPRETER
968                              || name[1] == KERN_JAVA_INTERPRETER
969 #endif
970 #ifdef KERN_JAVA_APPLETVIEWER
971                              || name[1] == KERN_JAVA_APPLETVIEWER
972 #endif
973                                  )))) {
974                         printpath(tcp, (size_t)info.oldval);
975                         tprintf(", %Zu, ", oldlen);
976                         if (info.newval == 0)
977                                 tprints("NULL");
978                         else if (syserror(tcp))
979                                 tprintf("%p", info.newval);
980                         else
981                                 printpath(tcp, (size_t)info.newval);
982                         tprintf(", %Zd", info.newlen);
983                 } else {
984                         tprintf("%p, %Zd, %p, %Zd", info.oldval, oldlen,
985                                 info.newval, info.newlen);
986                 }
987                 tprints("}");
988         }
989
990         free(name);
991         return 0;
992 }
993
994 #ifdef MIPS
995
996 #ifndef __NEW_UTS_LEN
997 #define __NEW_UTS_LEN 64
998 #endif
999
1000 static const struct xlat sysmips_operations[] = {
1001         { SETNAME,              "SETNAME"       },
1002         { FLUSH_CACHE,          "FLUSH_CACHE"   },
1003         { MIPS_FIXADE,          "MIPS_FIXADE"   },
1004         { MIPS_RDNVRAM,         "MIPS_RDNVRAM"  },
1005         { MIPS_ATOMIC_SET,      "MIPS_ATOMIC_SET"       },
1006         { 0, NULL }
1007 };
1008
1009 int sys_sysmips(struct tcb *tcp)
1010 {
1011         if (entering(tcp)) {
1012                 printxval(sysmips_operations, tcp->u_arg[0], "???");
1013                 if (!verbose(tcp)) {
1014                         tprintf("%ld, %ld, %ld", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
1015                 } else if (tcp->u_arg[0] == SETNAME) {
1016                         char nodename[__NEW_UTS_LEN + 1];
1017                         if (umovestr(tcp, tcp->u_arg[1], (__NEW_UTS_LEN + 1), nodename) < 0)
1018                                 tprintf(", %#lx", tcp->u_arg[1]);
1019                         else
1020                                 tprintf(", \"%.*s\"", (int)(__NEW_UTS_LEN + 1), nodename);
1021                 } else if (tcp->u_arg[0] == MIPS_ATOMIC_SET) {
1022                         tprintf(", %#lx, 0x%lx", tcp->u_arg[1], tcp->u_arg[2]);
1023                 } else if (tcp->u_arg[0] == MIPS_FIXADE) {
1024                         tprintf(", 0x%lx", tcp->u_arg[1]);
1025                 } else {
1026                         tprintf("%ld, %ld, %ld", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
1027                 }
1028         }
1029
1030         return 0;
1031 }
1032
1033 #endif /* MIPS */