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