]> granicus.if.org Git - strace/blob - file.c
Check for SA_RESTORER definition in <asm/signal.h>
[strace] / file.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 <dirent.h>
33 #include <sys/swap.h>
34
35 #if defined(SPARC) || defined(SPARC64)
36 struct stat {
37         unsigned short  st_dev;
38         unsigned int    st_ino;
39         unsigned short  st_mode;
40         short           st_nlink;
41         unsigned short  st_uid;
42         unsigned short  st_gid;
43         unsigned short  st_rdev;
44         unsigned int    st_size;
45         int             st_atime;
46         unsigned int    __unused1;
47         int             st_mtime;
48         unsigned int    __unused2;
49         int             st_ctime;
50         unsigned int    __unused3;
51         int             st_blksize;
52         int             st_blocks;
53         unsigned int    __unused4[2];
54 };
55 # if defined(SPARC64)
56 struct stat_sparc64 {
57         unsigned int    st_dev;
58         unsigned long   st_ino;
59         unsigned int    st_mode;
60         unsigned int    st_nlink;
61         unsigned int    st_uid;
62         unsigned int    st_gid;
63         unsigned int    st_rdev;
64         long            st_size;
65         long            st_atime;
66         long            st_mtime;
67         long            st_ctime;
68         long            st_blksize;
69         long            st_blocks;
70         unsigned long   __unused4[2];
71 };
72 # endif /* SPARC64 */
73 # define stat kernel_stat
74 # include <asm/stat.h>
75 # undef stat
76 #elif defined(X32)
77 struct stat {
78         unsigned long long      st_dev;
79         unsigned long long      st_ino;
80         unsigned long long      st_nlink;
81
82         unsigned int            st_mode;
83         unsigned int            st_uid;
84         unsigned int            st_gid;
85         unsigned int            __pad0;
86         unsigned long long      st_rdev;
87         long long               st_size;
88         long long               st_blksize;
89         long long               st_blocks;
90
91         unsigned long long      st_atime;
92         unsigned long long      st_atime_nsec;
93         unsigned long long      st_mtime;
94         unsigned long long      st_mtime_nsec;
95         unsigned long long      st_ctime;
96         unsigned long long      st_ctime_nsec;
97         long long               __unused[3];
98 };
99
100 struct stat64 {
101         unsigned long long      st_dev;
102         unsigned char           __pad0[4];
103         unsigned long           __st_ino;
104         unsigned int            st_mode;
105         unsigned int            st_nlink;
106         unsigned long           st_uid;
107         unsigned long           st_gid;
108         unsigned long long      st_rdev;
109         unsigned char           __pad3[4];
110         long long               st_size;
111         unsigned long           st_blksize;
112         unsigned long long      st_blocks;
113         unsigned long           st_atime;
114         unsigned long           st_atime_nsec;
115         unsigned long           st_mtime;
116         unsigned int            st_mtime_nsec;
117         unsigned long           st_ctime;
118         unsigned long           st_ctime_nsec;
119         unsigned long long      st_ino;
120 } __attribute__((packed));
121 # define HAVE_STAT64    1
122
123 struct __old_kernel_stat {
124         unsigned short st_dev;
125         unsigned short st_ino;
126         unsigned short st_mode;
127         unsigned short st_nlink;
128         unsigned short st_uid;
129         unsigned short st_gid;
130         unsigned short st_rdev;
131         unsigned int   st_size;
132         unsigned int   st_atime;
133         unsigned int   st_mtime;
134         unsigned int   st_ctime;
135 };
136 #else
137 # undef dev_t
138 # undef ino_t
139 # undef mode_t
140 # undef nlink_t
141 # undef uid_t
142 # undef gid_t
143 # undef off_t
144 # undef loff_t
145 # define dev_t __kernel_dev_t
146 # define ino_t __kernel_ino_t
147 # define mode_t __kernel_mode_t
148 # define nlink_t __kernel_nlink_t
149 # define uid_t __kernel_uid_t
150 # define gid_t __kernel_gid_t
151 # define off_t __kernel_off_t
152 # define loff_t __kernel_loff_t
153
154 # include <asm/stat.h>
155
156 # undef dev_t
157 # undef ino_t
158 # undef mode_t
159 # undef nlink_t
160 # undef uid_t
161 # undef gid_t
162 # undef off_t
163 # undef loff_t
164 # define dev_t dev_t
165 # define ino_t ino_t
166 # define mode_t mode_t
167 # define nlink_t nlink_t
168 # define uid_t uid_t
169 # define gid_t gid_t
170 # define off_t off_t
171 # define loff_t loff_t
172 #endif
173
174 #define stat libc_stat
175 #define stat64 libc_stat64
176 #include <sys/stat.h>
177 #undef stat
178 #undef stat64
179 /* These might be macros. */
180 #undef st_atime
181 #undef st_mtime
182 #undef st_ctime
183
184 #include <fcntl.h>
185 #ifdef HAVE_SYS_VFS_H
186 # include <sys/vfs.h>
187 #endif
188 #ifdef HAVE_LINUX_XATTR_H
189 # include <linux/xattr.h>
190 #else
191 # define XATTR_CREATE 1
192 # define XATTR_REPLACE 2
193 #endif
194
195 #ifdef MAJOR_IN_SYSMACROS
196 # include <sys/sysmacros.h>
197 #endif
198
199 #ifdef MAJOR_IN_MKDEV
200 # include <sys/mkdev.h>
201 #endif
202
203 #ifdef HAVE_SYS_ASYNCH_H
204 # include <sys/asynch.h>
205 #endif
206
207 struct kernel_dirent {
208         unsigned long   d_ino;
209         unsigned long   d_off;
210         unsigned short  d_reclen;
211         char            d_name[1];
212 };
213
214 const struct xlat open_access_modes[] = {
215         XLAT(O_RDONLY),
216         XLAT(O_WRONLY),
217         XLAT(O_RDWR),
218 #ifdef O_ACCMODE
219         XLAT(O_ACCMODE),
220 #endif
221         XLAT_END
222 };
223
224 const struct xlat open_mode_flags[] = {
225         XLAT(O_CREAT),
226         XLAT(O_EXCL),
227         XLAT(O_NOCTTY),
228         XLAT(O_TRUNC),
229         XLAT(O_APPEND),
230         XLAT(O_NONBLOCK),
231 #ifdef O_SYNC
232         XLAT(O_SYNC),
233 #endif
234 #ifdef O_ASYNC
235         XLAT(O_ASYNC),
236 #endif
237 #ifdef O_DSYNC
238         XLAT(O_DSYNC),
239 #endif
240 #ifdef O_RSYNC
241         XLAT(O_RSYNC),
242 #endif
243 #if defined(O_NDELAY) && (O_NDELAY != O_NONBLOCK)
244         XLAT(O_NDELAY),
245 #endif
246 #ifdef O_PRIV
247         XLAT(O_PRIV),
248 #endif
249 #ifdef O_DIRECT
250         XLAT(O_DIRECT),
251 #endif
252 #ifdef O_LARGEFILE
253 # if O_LARGEFILE == 0           /* biarch platforms in 64-bit mode */
254 #  undef O_LARGEFILE
255 #  ifdef SPARC64
256 #   define O_LARGEFILE  0x40000
257 #  elif defined X86_64 || defined S390X
258 #   define O_LARGEFILE  0100000
259 #  endif
260 # endif
261 # ifdef O_LARGEFILE
262         XLAT(O_LARGEFILE),
263 # endif
264 #endif
265 #ifdef O_DIRECTORY
266         XLAT(O_DIRECTORY),
267 #endif
268 #ifdef O_NOFOLLOW
269         XLAT(O_NOFOLLOW),
270 #endif
271 #ifdef O_NOATIME
272         XLAT(O_NOATIME),
273 #endif
274 #ifdef O_CLOEXEC
275         XLAT(O_CLOEXEC),
276 #endif
277 #ifdef O_PATH
278         XLAT(O_PATH),
279 #endif
280 #ifdef FNDELAY
281         XLAT(FNDELAY),
282 #endif
283 #ifdef FAPPEND
284         XLAT(FAPPEND),
285 #endif
286 #ifdef FMARK
287         XLAT(FMARK),
288 #endif
289 #ifdef FDEFER
290         XLAT(FDEFER),
291 #endif
292 #ifdef FASYNC
293         XLAT(FASYNC),
294 #endif
295 #ifdef FSHLOCK
296         XLAT(FSHLOCK),
297 #endif
298 #ifdef FEXLOCK
299         XLAT(FEXLOCK),
300 #endif
301 #ifdef FCREAT
302         XLAT(FCREAT),
303 #endif
304 #ifdef FTRUNC
305         XLAT(FTRUNC),
306 #endif
307 #ifdef FEXCL
308         XLAT(FEXCL),
309 #endif
310 #ifdef FNBIO
311         XLAT(FNBIO),
312 #endif
313 #ifdef FSYNC
314         XLAT(FSYNC),
315 #endif
316 #ifdef FNOCTTY
317         XLAT(FNOCTTY),
318 #endif
319 #ifdef O_SHLOCK
320         XLAT(O_SHLOCK),
321 #endif
322 #ifdef O_EXLOCK
323         XLAT(O_EXLOCK),
324 #endif
325         XLAT_END
326 };
327
328 #ifndef AT_FDCWD
329 # define AT_FDCWD                -100
330 #endif
331
332 /* The fd is an "int", so when decoding x86 on x86_64, we need to force sign
333  * extension to get the right value.  We do this by declaring fd as int here.
334  */
335 void
336 print_dirfd(struct tcb *tcp, int fd)
337 {
338         if (fd == AT_FDCWD)
339                 tprints("AT_FDCWD, ");
340         else {
341                 printfd(tcp, fd);
342                 tprints(", ");
343         }
344 }
345
346 /*
347  * low bits of the open(2) flags define access mode,
348  * other bits are real flags.
349  */
350 const char *
351 sprint_open_modes(mode_t flags)
352 {
353         static char outstr[(1 + ARRAY_SIZE(open_mode_flags)) * sizeof("O_LARGEFILE")];
354         char *p;
355         char sep;
356         const char *str;
357         const struct xlat *x;
358
359         sep = ' ';
360         p = stpcpy(outstr, "flags");
361         str = xlookup(open_access_modes, flags & 3);
362         if (str) {
363                 *p++ = sep;
364                 p = stpcpy(p, str);
365                 flags &= ~3;
366                 if (!flags)
367                         return outstr;
368                 sep = '|';
369         }
370
371         for (x = open_mode_flags; x->str; x++) {
372                 if ((flags & x->val) == x->val) {
373                         *p++ = sep;
374                         p = stpcpy(p, x->str);
375                         flags &= ~x->val;
376                         if (!flags)
377                                 return outstr;
378                         sep = '|';
379                 }
380         }
381         /* flags is still nonzero */
382         *p++ = sep;
383         sprintf(p, "%#x", flags);
384         return outstr;
385 }
386
387 void
388 tprint_open_modes(mode_t flags)
389 {
390         tprints(sprint_open_modes(flags) + sizeof("flags"));
391 }
392
393 static int
394 decode_open(struct tcb *tcp, int offset)
395 {
396         if (entering(tcp)) {
397                 printpath(tcp, tcp->u_arg[offset]);
398                 tprints(", ");
399                 /* flags */
400                 tprint_open_modes(tcp->u_arg[offset + 1]);
401                 if (tcp->u_arg[offset + 1] & O_CREAT) {
402                         /* mode */
403                         tprintf(", %#lo", tcp->u_arg[offset + 2]);
404                 }
405         }
406         return 0;
407 }
408
409 int
410 sys_open(struct tcb *tcp)
411 {
412         return decode_open(tcp, 0);
413 }
414
415 int
416 sys_openat(struct tcb *tcp)
417 {
418         if (entering(tcp))
419                 print_dirfd(tcp, tcp->u_arg[0]);
420         return decode_open(tcp, 1);
421 }
422
423 #if defined(SPARC) || defined(SPARC64)
424 static const struct xlat openmodessol[] = {
425         { 0,            "O_RDWR"        },
426         { 1,            "O_RDONLY"      },
427         { 2,            "O_WRONLY"      },
428         { 0x80,         "O_NONBLOCK"    },
429         { 8,            "O_APPEND"      },
430         { 0x100,        "O_CREAT"       },
431         { 0x200,        "O_TRUNC"       },
432         { 0x400,        "O_EXCL"        },
433         { 0x800,        "O_NOCTTY"      },
434         { 0x10,         "O_SYNC"        },
435         { 0x40,         "O_DSYNC"       },
436         { 0x8000,       "O_RSYNC"       },
437         { 4,            "O_NDELAY"      },
438         { 0x1000,       "O_PRIV"        },
439         XLAT_END
440 };
441
442 int
443 solaris_open(struct tcb *tcp)
444 {
445         if (entering(tcp)) {
446                 printpath(tcp, tcp->u_arg[0]);
447                 tprints(", ");
448                 /* flags */
449                 printflags(openmodessol, tcp->u_arg[1] + 1, "O_???");
450                 if (tcp->u_arg[1] & 0x100) {
451                         /* mode */
452                         tprintf(", %#lo", tcp->u_arg[2]);
453                 }
454         }
455         return 0;
456 }
457
458 #endif
459
460 int
461 sys_creat(struct tcb *tcp)
462 {
463         if (entering(tcp)) {
464                 printpath(tcp, tcp->u_arg[0]);
465                 tprintf(", %#lo", tcp->u_arg[1]);
466         }
467         return 0;
468 }
469
470 static const struct xlat access_flags[] = {
471         XLAT(F_OK),
472         XLAT(R_OK),
473         XLAT(W_OK),
474         XLAT(X_OK),
475 #ifdef EFF_ONLY_OK
476         XLAT(EFF_ONLY_OK),
477 #endif
478 #ifdef EX_OK
479         XLAT(EX_OK),
480 #endif
481         XLAT_END
482 };
483
484 static int
485 decode_access(struct tcb *tcp, int offset)
486 {
487         if (entering(tcp)) {
488                 printpath(tcp, tcp->u_arg[offset]);
489                 tprints(", ");
490                 printflags(access_flags, tcp->u_arg[offset + 1], "?_OK");
491         }
492         return 0;
493 }
494
495 int
496 sys_access(struct tcb *tcp)
497 {
498         return decode_access(tcp, 0);
499 }
500
501 int
502 sys_faccessat(struct tcb *tcp)
503 {
504         if (entering(tcp))
505                 print_dirfd(tcp, tcp->u_arg[0]);
506         return decode_access(tcp, 1);
507 }
508
509 int
510 sys_umask(struct tcb *tcp)
511 {
512         if (entering(tcp)) {
513                 tprintf("%#lo", tcp->u_arg[0]);
514         }
515         return RVAL_OCTAL;
516 }
517
518 const struct xlat whence_codes[] = {
519         XLAT(SEEK_SET),
520         XLAT(SEEK_CUR),
521         XLAT(SEEK_END),
522 #ifdef SEEK_DATA
523         XLAT(SEEK_DATA),
524 #endif
525 #ifdef SEEK_HOLE
526         XLAT(SEEK_HOLE),
527 #endif
528         XLAT_END
529 };
530
531 /* Linux kernel has exactly one version of lseek:
532  * fs/read_write.c::SYSCALL_DEFINE3(lseek, unsigned, fd, off_t, offset, unsigned, origin)
533  * In kernel, off_t is always the same as (kernel's) long
534  * (see include/uapi/asm-generic/posix_types.h),
535  * which means that on x32 we need to use tcp->ext_arg[N] to get offset argument.
536  * Use test/x32_lseek.c to test lseek decoding.
537  */
538 #if defined(LINUX_MIPSN32) || defined(X32)
539 int
540 sys_lseek(struct tcb *tcp)
541 {
542         long long offset;
543         int whence;
544
545         if (entering(tcp)) {
546                 printfd(tcp, tcp->u_arg[0]);
547                 offset = tcp->ext_arg[1];
548                 whence = tcp->u_arg[2];
549                 if (whence == SEEK_SET)
550                         tprintf(", %llu, ", offset);
551                 else
552                         tprintf(", %lld, ", offset);
553                 printxval(whence_codes, whence, "SEEK_???");
554         }
555         return RVAL_LUDECIMAL;
556 }
557 #else
558 int
559 sys_lseek(struct tcb *tcp)
560 {
561         long offset;
562         int whence;
563
564         if (entering(tcp)) {
565                 printfd(tcp, tcp->u_arg[0]);
566                 offset = tcp->u_arg[1];
567                 whence = tcp->u_arg[2];
568                 if (whence == SEEK_SET)
569                         tprintf(", %lu, ", offset);
570                 else
571                         tprintf(", %ld, ", offset);
572                 printxval(whence_codes, whence, "SEEK_???");
573         }
574         return RVAL_UDECIMAL;
575 }
576 #endif
577
578 /* llseek syscall takes explicitly two ulong arguments hi, lo,
579  * rather than one 64-bit argument for which LONG_LONG works
580  * appropriate for the native byte order.
581  *
582  * See kernel's fs/read_write.c::SYSCALL_DEFINE5(llseek, ...)
583  *
584  * hi,lo are "unsigned longs" and combined exactly this way in kernel:
585  * ((loff_t) hi << 32) | lo
586  * Note that for architectures with kernel's long wider than userspace long
587  * (such as x32), combining code will use *kernel's*, i.e. *wide* longs
588  * for hi and lo. We would need to use tcp->ext_arg[N] on x32...
589  * ...however, x32 (and x86_64) does not _have_ llseek syscall as such.
590  */
591 int
592 sys_llseek(struct tcb *tcp)
593 {
594         if (entering(tcp)) {
595                 printfd(tcp, tcp->u_arg[0]);
596                 if (tcp->u_arg[4] == SEEK_SET)
597                         tprintf(", %llu, ",
598                                 ((long long) tcp->u_arg[1]) << 32 |
599                                 (unsigned long long) (unsigned) tcp->u_arg[2]);
600                 else
601                         tprintf(", %lld, ",
602                                 ((long long) tcp->u_arg[1]) << 32 |
603                                 (unsigned long long) (unsigned) tcp->u_arg[2]);
604         }
605         else {
606                 long long off;
607                 if (syserror(tcp) || umove(tcp, tcp->u_arg[3], &off) < 0)
608                         tprintf("%#lx, ", tcp->u_arg[3]);
609                 else
610                         tprintf("[%llu], ", off);
611                 printxval(whence_codes, tcp->u_arg[4], "SEEK_???");
612         }
613         return 0;
614 }
615
616 int
617 sys_readahead(struct tcb *tcp)
618 {
619         if (entering(tcp)) {
620                 int argn;
621                 printfd(tcp, tcp->u_arg[0]);
622                 argn = printllval(tcp, ", %lld", 1);
623                 tprintf(", %ld", tcp->u_arg[argn]);
624         }
625         return 0;
626 }
627
628 int
629 sys_truncate(struct tcb *tcp)
630 {
631         if (entering(tcp)) {
632                 printpath(tcp, tcp->u_arg[0]);
633                 tprintf(", %lu", tcp->u_arg[1]);
634         }
635         return 0;
636 }
637
638 int
639 sys_truncate64(struct tcb *tcp)
640 {
641         if (entering(tcp)) {
642                 printpath(tcp, tcp->u_arg[0]);
643                 printllval(tcp, ", %llu", 1);
644         }
645         return 0;
646 }
647
648 int
649 sys_ftruncate(struct tcb *tcp)
650 {
651         if (entering(tcp)) {
652                 printfd(tcp, tcp->u_arg[0]);
653                 tprintf(", %lu", tcp->u_arg[1]);
654         }
655         return 0;
656 }
657
658 int
659 sys_ftruncate64(struct tcb *tcp)
660 {
661         if (entering(tcp)) {
662                 printfd(tcp, tcp->u_arg[0]);
663                 printllval(tcp, ", %llu", 1);
664         }
665         return 0;
666 }
667
668 /* several stats */
669
670 static const struct xlat modetypes[] = {
671         XLAT(S_IFREG),
672         XLAT(S_IFSOCK),
673         XLAT(S_IFIFO),
674         XLAT(S_IFLNK),
675         XLAT(S_IFDIR),
676         XLAT(S_IFBLK),
677         XLAT(S_IFCHR),
678         XLAT_END
679 };
680
681 static const char *
682 sprintmode(int mode)
683 {
684         static char buf[sizeof("S_IFSOCK|S_ISUID|S_ISGID|S_ISVTX|%o")
685                         + sizeof(int)*3
686                         + /*paranoia:*/ 8];
687         const char *s;
688
689         if ((mode & S_IFMT) == 0)
690                 s = "";
691         else if ((s = xlookup(modetypes, mode & S_IFMT)) == NULL) {
692                 sprintf(buf, "%#o", mode);
693                 return buf;
694         }
695         s = buf + sprintf(buf, "%s%s%s%s", s,
696                 (mode & S_ISUID) ? "|S_ISUID" : "",
697                 (mode & S_ISGID) ? "|S_ISGID" : "",
698                 (mode & S_ISVTX) ? "|S_ISVTX" : "");
699         mode &= ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX);
700         if (mode)
701                 sprintf((char*)s, "|%#o", mode);
702         s = (*buf == '|') ? buf + 1 : buf;
703         return *s ? s : "0";
704 }
705
706 static char *
707 sprinttime(time_t t)
708 {
709         struct tm *tmp;
710         static char buf[sizeof("yyyy/mm/dd-hh:mm:ss")];
711
712         if (t == 0) {
713                 strcpy(buf, "0");
714                 return buf;
715         }
716         tmp = localtime(&t);
717         if (tmp)
718                 snprintf(buf, sizeof buf, "%02d/%02d/%02d-%02d:%02d:%02d",
719                         tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
720                         tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
721         else
722                 snprintf(buf, sizeof buf, "%lu", (unsigned long) t);
723
724         return buf;
725 }
726
727 #if defined(SPARC) || defined(SPARC64)
728 typedef struct {
729         int     tv_sec;
730         int     tv_nsec;
731 } timestruct_t;
732
733 struct solstat {
734         unsigned        st_dev;
735         int             st_pad1[3];     /* network id */
736         unsigned        st_ino;
737         unsigned        st_mode;
738         unsigned        st_nlink;
739         unsigned        st_uid;
740         unsigned        st_gid;
741         unsigned        st_rdev;
742         int             st_pad2[2];
743         int             st_size;
744         int             st_pad3;        /* st_size, off_t expansion */
745         timestruct_t    st_atime;
746         timestruct_t    st_mtime;
747         timestruct_t    st_ctime;
748         int             st_blksize;
749         int             st_blocks;
750         char            st_fstype[16];
751         int             st_pad4[8];     /* expansion area */
752 };
753
754 static void
755 printstatsol(struct tcb *tcp, long addr)
756 {
757         struct solstat statbuf;
758
759         if (umove(tcp, addr, &statbuf) < 0) {
760                 tprints("{...}");
761                 return;
762         }
763         if (!abbrev(tcp)) {
764                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
765                         (unsigned long) ((statbuf.st_dev >> 18) & 0x3fff),
766                         (unsigned long) (statbuf.st_dev & 0x3ffff),
767                         (unsigned long) statbuf.st_ino,
768                         sprintmode(statbuf.st_mode));
769                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
770                         (unsigned long) statbuf.st_nlink,
771                         (unsigned long) statbuf.st_uid,
772                         (unsigned long) statbuf.st_gid);
773                 tprintf("st_blksize=%lu, ", (unsigned long) statbuf.st_blksize);
774                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
775         }
776         else
777                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
778         switch (statbuf.st_mode & S_IFMT) {
779         case S_IFCHR: case S_IFBLK:
780                 tprintf("st_rdev=makedev(%lu, %lu), ",
781                         (unsigned long) ((statbuf.st_rdev >> 18) & 0x3fff),
782                         (unsigned long) (statbuf.st_rdev & 0x3ffff));
783                 break;
784         default:
785                 tprintf("st_size=%u, ", statbuf.st_size);
786                 break;
787         }
788         if (!abbrev(tcp)) {
789                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime.tv_sec));
790                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime.tv_sec));
791                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime.tv_sec));
792         }
793         else
794                 tprints("...}");
795 }
796
797 # if defined(SPARC64)
798 static void
799 printstat_sparc64(struct tcb *tcp, long addr)
800 {
801         struct stat_sparc64 statbuf;
802
803         if (umove(tcp, addr, &statbuf) < 0) {
804                 tprints("{...}");
805                 return;
806         }
807
808         if (!abbrev(tcp)) {
809                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
810                         (unsigned long) major(statbuf.st_dev),
811                         (unsigned long) minor(statbuf.st_dev),
812                         (unsigned long) statbuf.st_ino,
813                         sprintmode(statbuf.st_mode));
814                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
815                         (unsigned long) statbuf.st_nlink,
816                         (unsigned long) statbuf.st_uid,
817                         (unsigned long) statbuf.st_gid);
818                 tprintf("st_blksize=%lu, ",
819                         (unsigned long) statbuf.st_blksize);
820                 tprintf("st_blocks=%lu, ",
821                         (unsigned long) statbuf.st_blocks);
822         }
823         else
824                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
825         switch (statbuf.st_mode & S_IFMT) {
826         case S_IFCHR: case S_IFBLK:
827                 tprintf("st_rdev=makedev(%lu, %lu), ",
828                         (unsigned long) major(statbuf.st_rdev),
829                         (unsigned long) minor(statbuf.st_rdev));
830                 break;
831         default:
832                 tprintf("st_size=%lu, ", statbuf.st_size);
833                 break;
834         }
835         if (!abbrev(tcp)) {
836                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
837                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
838                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
839         }
840         else
841                 tprints("...}");
842 }
843 # endif /* SPARC64 */
844 #endif /* SPARC[64] */
845
846 #if defined POWERPC64
847 struct stat_powerpc32 {
848         unsigned int    st_dev;
849         unsigned int    st_ino;
850         unsigned int    st_mode;
851         unsigned short  st_nlink;
852         unsigned int    st_uid;
853         unsigned int    st_gid;
854         unsigned int    st_rdev;
855         unsigned int    st_size;
856         unsigned int    st_blksize;
857         unsigned int    st_blocks;
858         unsigned int    st_atime;
859         unsigned int    st_atime_nsec;
860         unsigned int    st_mtime;
861         unsigned int    st_mtime_nsec;
862         unsigned int    st_ctime;
863         unsigned int    st_ctime_nsec;
864         unsigned int    __unused4;
865         unsigned int    __unused5;
866 };
867
868 static void
869 printstat_powerpc32(struct tcb *tcp, long addr)
870 {
871         struct stat_powerpc32 statbuf;
872
873         if (umove(tcp, addr, &statbuf) < 0) {
874                 tprints("{...}");
875                 return;
876         }
877
878         if (!abbrev(tcp)) {
879                 tprintf("{st_dev=makedev(%u, %u), st_ino=%u, st_mode=%s, ",
880                         major(statbuf.st_dev), minor(statbuf.st_dev),
881                         statbuf.st_ino,
882                         sprintmode(statbuf.st_mode));
883                 tprintf("st_nlink=%u, st_uid=%u, st_gid=%u, ",
884                         statbuf.st_nlink, statbuf.st_uid, statbuf.st_gid);
885                 tprintf("st_blksize=%u, ", statbuf.st_blksize);
886                 tprintf("st_blocks=%u, ", statbuf.st_blocks);
887         }
888         else
889                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
890         switch (statbuf.st_mode & S_IFMT) {
891         case S_IFCHR: case S_IFBLK:
892                 tprintf("st_rdev=makedev(%lu, %lu), ",
893                         (unsigned long) major(statbuf.st_rdev),
894                         (unsigned long) minor(statbuf.st_rdev));
895                 break;
896         default:
897                 tprintf("st_size=%u, ", statbuf.st_size);
898                 break;
899         }
900         if (!abbrev(tcp)) {
901                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
902                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
903                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
904         }
905         else
906                 tprints("...}");
907 }
908 #endif /* POWERPC64 */
909
910 static const struct xlat fileflags[] = {
911         XLAT_END
912 };
913
914 static void
915 realprintstat(struct tcb *tcp, struct stat *statbuf)
916 {
917         if (!abbrev(tcp)) {
918                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
919                         (unsigned long) major(statbuf->st_dev),
920                         (unsigned long) minor(statbuf->st_dev),
921                         (unsigned long) statbuf->st_ino,
922                         sprintmode(statbuf->st_mode));
923                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
924                         (unsigned long) statbuf->st_nlink,
925                         (unsigned long) statbuf->st_uid,
926                         (unsigned long) statbuf->st_gid);
927 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
928                 tprintf("st_blksize=%lu, ", (unsigned long) statbuf->st_blksize);
929 #endif
930 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
931                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf->st_blocks);
932 #endif
933         }
934         else
935                 tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode));
936         switch (statbuf->st_mode & S_IFMT) {
937         case S_IFCHR: case S_IFBLK:
938 #ifdef HAVE_STRUCT_STAT_ST_RDEV
939                 tprintf("st_rdev=makedev(%lu, %lu), ",
940                         (unsigned long) major(statbuf->st_rdev),
941                         (unsigned long) minor(statbuf->st_rdev));
942 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
943                 tprintf("st_size=makedev(%lu, %lu), ",
944                         (unsigned long) major(statbuf->st_size),
945                         (unsigned long) minor(statbuf->st_size));
946 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
947                 break;
948         default:
949                 tprintf("st_size=%lu, ", (unsigned long) statbuf->st_size);
950                 break;
951         }
952         if (!abbrev(tcp)) {
953                 tprintf("st_atime=%s, ", sprinttime(statbuf->st_atime));
954                 tprintf("st_mtime=%s, ", sprinttime(statbuf->st_mtime));
955                 tprintf("st_ctime=%s", sprinttime(statbuf->st_ctime));
956 #if HAVE_STRUCT_STAT_ST_FLAGS
957                 tprints(", st_flags=");
958                 printflags(fileflags, statbuf->st_flags, "UF_???");
959 #endif
960 #if HAVE_STRUCT_STAT_ST_ACLCNT
961                 tprintf(", st_aclcnt=%d", statbuf->st_aclcnt);
962 #endif
963 #if HAVE_STRUCT_STAT_ST_LEVEL
964                 tprintf(", st_level=%ld", statbuf->st_level);
965 #endif
966 #if HAVE_STRUCT_STAT_ST_FSTYPE
967                 tprintf(", st_fstype=%.*s",
968                         (int) sizeof statbuf->st_fstype, statbuf->st_fstype);
969 #endif
970 #if HAVE_STRUCT_STAT_ST_GEN
971                 tprintf(", st_gen=%u", statbuf->st_gen);
972 #endif
973                 tprints("}");
974         }
975         else
976                 tprints("...}");
977 }
978
979 #ifndef X32
980 static void
981 printstat(struct tcb *tcp, long addr)
982 {
983         struct stat statbuf;
984
985         if (!addr) {
986                 tprints("NULL");
987                 return;
988         }
989         if (syserror(tcp) || !verbose(tcp)) {
990                 tprintf("%#lx", addr);
991                 return;
992         }
993
994 #if defined(SPARC) || defined(SPARC64)
995         if (current_personality == 1) {
996                 printstatsol(tcp, addr);
997                 return;
998         }
999 #ifdef SPARC64
1000         else if (current_personality == 2) {
1001                 printstat_sparc64(tcp, addr);
1002                 return;
1003         }
1004 #endif
1005 #endif /* SPARC[64] */
1006
1007 #if defined POWERPC64
1008         if (current_personality == 1) {
1009                 printstat_powerpc32(tcp, addr);
1010                 return;
1011         }
1012 #endif
1013
1014         if (umove(tcp, addr, &statbuf) < 0) {
1015                 tprints("{...}");
1016                 return;
1017         }
1018
1019         realprintstat(tcp, &statbuf);
1020 }
1021 #else /* X32 */
1022 # define printstat printstat64
1023 #endif
1024
1025 #if !defined HAVE_STAT64 && defined X86_64
1026 /*
1027  * Linux x86_64 has unified `struct stat' but its i386 biarch needs
1028  * `struct stat64'.  Its <asm-i386/stat.h> definition expects 32-bit `long'.
1029  * <linux/include/asm-x86_64/ia32.h> is not in the public includes set.
1030  * __GNUC__ is needed for the required __attribute__ below.
1031  */
1032 struct stat64 {
1033         unsigned long long      st_dev;
1034         unsigned char   __pad0[4];
1035         unsigned int    __st_ino;
1036         unsigned int    st_mode;
1037         unsigned int    st_nlink;
1038         unsigned int    st_uid;
1039         unsigned int    st_gid;
1040         unsigned long long      st_rdev;
1041         unsigned char   __pad3[4];
1042         long long       st_size;
1043         unsigned int    st_blksize;
1044         unsigned long long      st_blocks;
1045         unsigned int    st_atime;
1046         unsigned int    st_atime_nsec;
1047         unsigned int    st_mtime;
1048         unsigned int    st_mtime_nsec;
1049         unsigned int    st_ctime;
1050         unsigned int    st_ctime_nsec;
1051         unsigned long long      st_ino;
1052 } __attribute__((packed));
1053 # define HAVE_STAT64    1
1054 # define STAT64_SIZE    96
1055 #endif
1056
1057 #ifdef HAVE_STAT64
1058 static void
1059 printstat64(struct tcb *tcp, long addr)
1060 {
1061 #ifdef X32
1062         struct stat statbuf;
1063 #else
1064         struct stat64 statbuf;
1065 #endif
1066
1067 #ifdef STAT64_SIZE
1068         (void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
1069 #endif
1070
1071         if (!addr) {
1072                 tprints("NULL");
1073                 return;
1074         }
1075         if (syserror(tcp) || !verbose(tcp)) {
1076                 tprintf("%#lx", addr);
1077                 return;
1078         }
1079
1080 #if defined(SPARC) || defined(SPARC64)
1081         if (current_personality == 1) {
1082                 printstatsol(tcp, addr);
1083                 return;
1084         }
1085 # ifdef SPARC64
1086         else if (current_personality == 2) {
1087                 printstat_sparc64(tcp, addr);
1088                 return;
1089         }
1090 # endif
1091 #endif /* SPARC[64] */
1092
1093 #if defined X86_64
1094         if (current_personality != 1) {
1095                 printstat(tcp, addr);
1096                 return;
1097         }
1098 #endif
1099
1100         if (umove(tcp, addr, &statbuf) < 0) {
1101                 tprints("{...}");
1102                 return;
1103         }
1104
1105         if (!abbrev(tcp)) {
1106                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
1107                         (unsigned long) major(statbuf.st_dev),
1108                         (unsigned long) minor(statbuf.st_dev),
1109                         (unsigned long long) statbuf.st_ino,
1110                         sprintmode(statbuf.st_mode));
1111                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
1112                         (unsigned long) statbuf.st_nlink,
1113                         (unsigned long) statbuf.st_uid,
1114                         (unsigned long) statbuf.st_gid);
1115 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1116                 tprintf("st_blksize=%lu, ",
1117                         (unsigned long) statbuf.st_blksize);
1118 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
1119 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1120                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
1121 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
1122         }
1123         else
1124                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
1125         switch (statbuf.st_mode & S_IFMT) {
1126         case S_IFCHR: case S_IFBLK:
1127 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1128                 tprintf("st_rdev=makedev(%lu, %lu), ",
1129                         (unsigned long) major(statbuf.st_rdev),
1130                         (unsigned long) minor(statbuf.st_rdev));
1131 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
1132                 tprintf("st_size=makedev(%lu, %lu), ",
1133                         (unsigned long) major(statbuf.st_size),
1134                         (unsigned long) minor(statbuf.st_size));
1135 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
1136                 break;
1137         default:
1138                 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
1139                 break;
1140         }
1141         if (!abbrev(tcp)) {
1142                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
1143                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
1144                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
1145 #if HAVE_STRUCT_STAT_ST_FLAGS
1146                 tprints(", st_flags=");
1147                 printflags(fileflags, statbuf.st_flags, "UF_???");
1148 #endif
1149 #if HAVE_STRUCT_STAT_ST_ACLCNT
1150                 tprintf(", st_aclcnt=%d", statbuf.st_aclcnt);
1151 #endif
1152 #if HAVE_STRUCT_STAT_ST_LEVEL
1153                 tprintf(", st_level=%ld", statbuf.st_level);
1154 #endif
1155 #if HAVE_STRUCT_STAT_ST_FSTYPE
1156                 tprintf(", st_fstype=%.*s",
1157                         (int) sizeof statbuf.st_fstype, statbuf.st_fstype);
1158 #endif
1159 #if HAVE_STRUCT_STAT_ST_GEN
1160                 tprintf(", st_gen=%u", statbuf.st_gen);
1161 #endif
1162                 tprints("}");
1163         }
1164         else
1165                 tprints("...}");
1166 }
1167 #endif /* HAVE_STAT64 */
1168
1169 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1170 static void
1171 convertoldstat(const struct __old_kernel_stat *oldbuf, struct stat *newbuf)
1172 {
1173         newbuf->st_dev = oldbuf->st_dev;
1174         newbuf->st_ino = oldbuf->st_ino;
1175         newbuf->st_mode = oldbuf->st_mode;
1176         newbuf->st_nlink = oldbuf->st_nlink;
1177         newbuf->st_uid = oldbuf->st_uid;
1178         newbuf->st_gid = oldbuf->st_gid;
1179         newbuf->st_rdev = oldbuf->st_rdev;
1180         newbuf->st_size = oldbuf->st_size;
1181         newbuf->st_atime = oldbuf->st_atime;
1182         newbuf->st_mtime = oldbuf->st_mtime;
1183         newbuf->st_ctime = oldbuf->st_ctime;
1184         newbuf->st_blksize = 0; /* not supported in old_stat */
1185         newbuf->st_blocks = 0; /* not supported in old_stat */
1186 }
1187
1188 static void
1189 printoldstat(struct tcb *tcp, long addr)
1190 {
1191         struct __old_kernel_stat statbuf;
1192         struct stat newstatbuf;
1193
1194         if (!addr) {
1195                 tprints("NULL");
1196                 return;
1197         }
1198         if (syserror(tcp) || !verbose(tcp)) {
1199                 tprintf("%#lx", addr);
1200                 return;
1201         }
1202
1203 # if defined(SPARC) || defined(SPARC64)
1204         if (current_personality == 1) {
1205                 printstatsol(tcp, addr);
1206                 return;
1207         }
1208 # endif
1209
1210         if (umove(tcp, addr, &statbuf) < 0) {
1211                 tprints("{...}");
1212                 return;
1213         }
1214
1215         convertoldstat(&statbuf, &newstatbuf);
1216         realprintstat(tcp, &newstatbuf);
1217 }
1218 #endif
1219
1220 int
1221 sys_stat(struct tcb *tcp)
1222 {
1223         if (entering(tcp)) {
1224                 printpath(tcp, tcp->u_arg[0]);
1225                 tprints(", ");
1226         } else {
1227                 printstat(tcp, tcp->u_arg[1]);
1228         }
1229         return 0;
1230 }
1231
1232 #ifdef X32
1233 static void
1234 printstat64_x32(struct tcb *tcp, long addr)
1235 {
1236         struct stat64 statbuf;
1237
1238         if (!addr) {
1239                 tprints("NULL");
1240                 return;
1241         }
1242         if (syserror(tcp) || !verbose(tcp)) {
1243                 tprintf("%#lx", addr);
1244                 return;
1245         }
1246
1247         if (umove(tcp, addr, &statbuf) < 0) {
1248                 tprints("{...}");
1249                 return;
1250         }
1251
1252         if (!abbrev(tcp)) {
1253                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
1254                         (unsigned long) major(statbuf.st_dev),
1255                         (unsigned long) minor(statbuf.st_dev),
1256                         (unsigned long long) statbuf.st_ino,
1257                         sprintmode(statbuf.st_mode));
1258                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
1259                         (unsigned long) statbuf.st_nlink,
1260                         (unsigned long) statbuf.st_uid,
1261                         (unsigned long) statbuf.st_gid);
1262                 tprintf("st_blksize=%lu, ",
1263                         (unsigned long) statbuf.st_blksize);
1264                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
1265         }
1266         else
1267                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
1268         switch (statbuf.st_mode & S_IFMT) {
1269         case S_IFCHR: case S_IFBLK:
1270                 tprintf("st_rdev=makedev(%lu, %lu), ",
1271                         (unsigned long) major(statbuf.st_rdev),
1272                         (unsigned long) minor(statbuf.st_rdev));
1273                 break;
1274         default:
1275                 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
1276                 break;
1277         }
1278         if (!abbrev(tcp)) {
1279                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
1280                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
1281                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
1282                 tprints("}");
1283         }
1284         else
1285                 tprints("...}");
1286 }
1287 #endif /* X32 */
1288
1289 int
1290 sys_stat64(struct tcb *tcp)
1291 {
1292 #ifdef HAVE_STAT64
1293         if (entering(tcp)) {
1294                 printpath(tcp, tcp->u_arg[0]);
1295                 tprints(", ");
1296         } else {
1297 # ifdef X32
1298                 printstat64_x32(tcp, tcp->u_arg[1]);
1299 # else
1300                 printstat64(tcp, tcp->u_arg[1]);
1301 # endif
1302         }
1303         return 0;
1304 #else
1305         return printargs(tcp);
1306 #endif
1307 }
1308
1309 #ifndef AT_SYMLINK_NOFOLLOW
1310 # define AT_SYMLINK_NOFOLLOW    0x100
1311 #endif
1312 #ifndef AT_REMOVEDIR
1313 # define AT_REMOVEDIR           0x200
1314 #endif
1315 #ifndef AT_SYMLINK_FOLLOW
1316 # define AT_SYMLINK_FOLLOW      0x400
1317 #endif
1318 #ifndef AT_NO_AUTOMOUNT
1319 # define AT_NO_AUTOMOUNT        0x800
1320 #endif
1321 #ifndef AT_EMPTY_PATH
1322 # define AT_EMPTY_PATH          0x1000
1323 #endif
1324
1325 static const struct xlat at_flags[] = {
1326         XLAT(AT_SYMLINK_NOFOLLOW),
1327         XLAT(AT_REMOVEDIR),
1328         XLAT(AT_SYMLINK_FOLLOW),
1329         XLAT(AT_NO_AUTOMOUNT),
1330         XLAT(AT_EMPTY_PATH),
1331         XLAT_END
1332 };
1333
1334 int
1335 sys_newfstatat(struct tcb *tcp)
1336 {
1337         if (entering(tcp)) {
1338                 print_dirfd(tcp, tcp->u_arg[0]);
1339                 printpath(tcp, tcp->u_arg[1]);
1340                 tprints(", ");
1341         } else {
1342 #ifdef POWERPC64
1343                 if (current_personality == 0)
1344                         printstat(tcp, tcp->u_arg[2]);
1345                 else
1346                         printstat64(tcp, tcp->u_arg[2]);
1347 #elif defined HAVE_STAT64
1348                 printstat64(tcp, tcp->u_arg[2]);
1349 #else
1350                 printstat(tcp, tcp->u_arg[2]);
1351 #endif
1352                 tprints(", ");
1353                 printflags(at_flags, tcp->u_arg[3], "AT_???");
1354         }
1355         return 0;
1356 }
1357
1358 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1359 int
1360 sys_oldstat(struct tcb *tcp)
1361 {
1362         if (entering(tcp)) {
1363                 printpath(tcp, tcp->u_arg[0]);
1364                 tprints(", ");
1365         } else {
1366                 printoldstat(tcp, tcp->u_arg[1]);
1367         }
1368         return 0;
1369 }
1370 #endif
1371
1372 int
1373 sys_fstat(struct tcb *tcp)
1374 {
1375         if (entering(tcp)) {
1376                 printfd(tcp, tcp->u_arg[0]);
1377                 tprints(", ");
1378         } else {
1379                 printstat(tcp, tcp->u_arg[1]);
1380         }
1381         return 0;
1382 }
1383
1384 int
1385 sys_fstat64(struct tcb *tcp)
1386 {
1387 #ifdef HAVE_STAT64
1388         if (entering(tcp)) {
1389                 printfd(tcp, tcp->u_arg[0]);
1390                 tprints(", ");
1391         } else {
1392 # ifdef X32
1393                 printstat64_x32(tcp, tcp->u_arg[1]);
1394 # else
1395                 printstat64(tcp, tcp->u_arg[1]);
1396 # endif
1397         }
1398         return 0;
1399 #else
1400         return printargs(tcp);
1401 #endif
1402 }
1403
1404 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1405 int
1406 sys_oldfstat(struct tcb *tcp)
1407 {
1408         if (entering(tcp)) {
1409                 printfd(tcp, tcp->u_arg[0]);
1410                 tprints(", ");
1411         } else {
1412                 printoldstat(tcp, tcp->u_arg[1]);
1413         }
1414         return 0;
1415 }
1416 #endif
1417
1418 #if defined(SPARC) || defined(SPARC64)
1419
1420 int
1421 sys_xstat(struct tcb *tcp)
1422 {
1423         if (entering(tcp)) {
1424                 tprintf("%ld, ", tcp->u_arg[0]);
1425                 printpath(tcp, tcp->u_arg[1]);
1426                 tprints(", ");
1427         } else {
1428 # ifdef _STAT64_VER
1429                 if (tcp->u_arg[0] == _STAT64_VER)
1430                         printstat64(tcp, tcp->u_arg[2]);
1431                 else
1432 # endif
1433                 printstat(tcp, tcp->u_arg[2]);
1434         }
1435         return 0;
1436 }
1437
1438 int
1439 sys_fxstat(struct tcb *tcp)
1440 {
1441         if (entering(tcp))
1442                 tprintf("%ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1]);
1443         else {
1444 # ifdef _STAT64_VER
1445                 if (tcp->u_arg[0] == _STAT64_VER)
1446                         printstat64(tcp, tcp->u_arg[2]);
1447                 else
1448 # endif
1449                 printstat(tcp, tcp->u_arg[2]);
1450         }
1451         return 0;
1452 }
1453
1454 int
1455 sys_lxstat(struct tcb *tcp)
1456 {
1457         if (entering(tcp)) {
1458                 tprintf("%ld, ", tcp->u_arg[0]);
1459                 printpath(tcp, tcp->u_arg[1]);
1460                 tprints(", ");
1461         } else {
1462 # ifdef _STAT64_VER
1463                 if (tcp->u_arg[0] == _STAT64_VER)
1464                         printstat64(tcp, tcp->u_arg[2]);
1465                 else
1466 # endif
1467                 printstat(tcp, tcp->u_arg[2]);
1468         }
1469         return 0;
1470 }
1471
1472 int
1473 sys_xmknod(struct tcb *tcp)
1474 {
1475         int mode = tcp->u_arg[2];
1476
1477         if (entering(tcp)) {
1478                 tprintf("%ld, ", tcp->u_arg[0]);
1479                 printpath(tcp, tcp->u_arg[1]);
1480                 tprintf(", %s", sprintmode(mode));
1481                 switch (mode & S_IFMT) {
1482                 case S_IFCHR: case S_IFBLK:
1483                         tprintf(", makedev(%lu, %lu)",
1484                                 (unsigned long) ((tcp->u_arg[3] >> 18) & 0x3fff),
1485                                 (unsigned long) (tcp->u_arg[3] & 0x3ffff));
1486                         break;
1487                 default:
1488                         break;
1489                 }
1490         }
1491         return 0;
1492 }
1493
1494 # ifdef HAVE_SYS_ACL_H
1495
1496 #  include <sys/acl.h>
1497
1498 static const struct xlat aclcmds[] = {
1499 #  ifdef SETACL
1500         XLAT(SETACL),
1501 #  endif
1502 #  ifdef GETACL
1503         XLAT(GETACL),
1504 #  endif
1505 #  ifdef GETACLCNT
1506         XLAT(GETACLCNT),
1507 #  endif
1508 #  ifdef ACL_GET
1509         XLAT(ACL_GET),
1510 #  endif
1511 #  ifdef ACL_SET
1512         XLAT(ACL_SET),
1513 #  endif
1514 #  ifdef ACL_CNT
1515         XLAT(ACL_CNT),
1516 #  endif
1517         XLAT_END
1518 };
1519
1520 int
1521 sys_acl(struct tcb *tcp)
1522 {
1523         if (entering(tcp)) {
1524                 printpath(tcp, tcp->u_arg[0]);
1525                 tprints(", ");
1526                 printxval(aclcmds, tcp->u_arg[1], "???ACL???");
1527                 tprintf(", %ld", tcp->u_arg[2]);
1528                 /*
1529                  * FIXME - dump out the list of aclent_t's pointed to
1530                  * by "tcp->u_arg[3]" if it's not NULL.
1531                  */
1532                 if (tcp->u_arg[3])
1533                         tprintf(", %#lx", tcp->u_arg[3]);
1534                 else
1535                         tprints(", NULL");
1536         }
1537         return 0;
1538 }
1539
1540 int
1541 sys_facl(struct tcb *tcp)
1542 {
1543         if (entering(tcp)) {
1544                 tprintf("%ld, ", tcp->u_arg[0]);
1545                 printxval(aclcmds, tcp->u_arg[1], "???ACL???");
1546                 tprintf(", %ld", tcp->u_arg[2]);
1547                 /*
1548                  * FIXME - dump out the list of aclent_t's pointed to
1549                  * by "tcp->u_arg[3]" if it's not NULL.
1550                  */
1551                 if (tcp->u_arg[3])
1552                         tprintf(", %#lx", tcp->u_arg[3]);
1553                 else
1554                         tprints(", NULL");
1555         }
1556         return 0;
1557 }
1558
1559 static const struct xlat aclipc[] = {
1560 #  ifdef IPC_SHM
1561         XLAT(IPC_SHM),
1562 #  endif
1563 #  ifdef IPC_SEM
1564         XLAT(IPC_SEM),
1565 #  endif
1566 #  ifdef IPC_MSG
1567         XLAT(IPC_MSG),
1568 #  endif
1569         XLAT_END
1570 };
1571
1572 int
1573 sys_aclipc(struct tcb *tcp)
1574 {
1575         if (entering(tcp)) {
1576                 printxval(aclipc, tcp->u_arg[0], "???IPC???");
1577                 tprintf(", %#lx, ", tcp->u_arg[1]);
1578                 printxval(aclcmds, tcp->u_arg[2], "???ACL???");
1579                 tprintf(", %ld", tcp->u_arg[3]);
1580                 /*
1581                  * FIXME - dump out the list of aclent_t's pointed to
1582                  * by "tcp->u_arg[4]" if it's not NULL.
1583                  */
1584                 if (tcp->u_arg[4])
1585                         tprintf(", %#lx", tcp->u_arg[4]);
1586                 else
1587                         tprints(", NULL");
1588         }
1589         return 0;
1590 }
1591
1592 # endif /* HAVE_SYS_ACL_H */
1593
1594 #endif /* SPARC[64] */
1595
1596 static const struct xlat fsmagic[] = {
1597         { 0x73757245,   "CODA_SUPER_MAGIC"      },
1598         { 0x012ff7b7,   "COH_SUPER_MAGIC"       },
1599         { 0x1373,       "DEVFS_SUPER_MAGIC"     },
1600         { 0x1cd1,       "DEVPTS_SUPER_MAGIC"    },
1601         { 0x414A53,     "EFS_SUPER_MAGIC"       },
1602         { 0xef51,       "EXT2_OLD_SUPER_MAGIC"  },
1603         { 0xef53,       "EXT2_SUPER_MAGIC"      },
1604         { 0x137d,       "EXT_SUPER_MAGIC"       },
1605         { 0xf995e849,   "HPFS_SUPER_MAGIC"      },
1606         { 0x9660,       "ISOFS_SUPER_MAGIC"     },
1607         { 0x137f,       "MINIX_SUPER_MAGIC"     },
1608         { 0x138f,       "MINIX_SUPER_MAGIC2"    },
1609         { 0x2468,       "MINIX2_SUPER_MAGIC"    },
1610         { 0x2478,       "MINIX2_SUPER_MAGIC2"   },
1611         { 0x4d44,       "MSDOS_SUPER_MAGIC"     },
1612         { 0x564c,       "NCP_SUPER_MAGIC"       },
1613         { 0x6969,       "NFS_SUPER_MAGIC"       },
1614         { 0x9fa0,       "PROC_SUPER_MAGIC"      },
1615         { 0x002f,       "QNX4_SUPER_MAGIC"      },
1616         { 0x52654973,   "REISERFS_SUPER_MAGIC"  },
1617         { 0x02011994,   "SHMFS_SUPER_MAGIC"     },
1618         { 0x517b,       "SMB_SUPER_MAGIC"       },
1619         { 0x012ff7b6,   "SYSV2_SUPER_MAGIC"     },
1620         { 0x012ff7b5,   "SYSV4_SUPER_MAGIC"     },
1621         { 0x00011954,   "UFS_MAGIC"             },
1622         { 0x54190100,   "UFS_CIGAM"             },
1623         { 0x012ff7b4,   "XENIX_SUPER_MAGIC"     },
1624         { 0x012fd16d,   "XIAFS_SUPER_MAGIC"     },
1625         { 0x62656572,   "SYSFS_MAGIC"           },
1626         XLAT_END
1627 };
1628
1629 static const char *
1630 sprintfstype(int magic)
1631 {
1632         static char buf[32];
1633         const char *s;
1634
1635         s = xlookup(fsmagic, magic);
1636         if (s) {
1637                 sprintf(buf, "\"%s\"", s);
1638                 return buf;
1639         }
1640         sprintf(buf, "%#x", magic);
1641         return buf;
1642 }
1643
1644 static void
1645 printstatfs(struct tcb *tcp, long addr)
1646 {
1647         struct statfs statbuf;
1648
1649         if (syserror(tcp) || !verbose(tcp)) {
1650                 tprintf("%#lx", addr);
1651                 return;
1652         }
1653         if (umove(tcp, addr, &statbuf) < 0) {
1654                 tprints("{...}");
1655                 return;
1656         }
1657 #ifdef ALPHA
1658
1659         tprintf("{f_type=%s, f_fbsize=%u, f_blocks=%u, f_bfree=%u, ",
1660                 sprintfstype(statbuf.f_type),
1661                 statbuf.f_bsize, statbuf.f_blocks, statbuf.f_bfree);
1662         tprintf("f_bavail=%u, f_files=%u, f_ffree=%u, f_fsid={%d, %d}, f_namelen=%u",
1663                 statbuf.f_bavail, statbuf.f_files, statbuf.f_ffree,
1664                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1],
1665                 statbuf.f_namelen);
1666 #else /* !ALPHA */
1667         tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ",
1668                 sprintfstype(statbuf.f_type),
1669                 (unsigned long)statbuf.f_bsize,
1670                 (unsigned long)statbuf.f_blocks,
1671                 (unsigned long)statbuf.f_bfree);
1672         tprintf("f_bavail=%lu, f_files=%lu, f_ffree=%lu, f_fsid={%d, %d}",
1673                 (unsigned long)statbuf.f_bavail,
1674                 (unsigned long)statbuf.f_files,
1675                 (unsigned long)statbuf.f_ffree,
1676                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
1677         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
1678 #endif /* !ALPHA */
1679 #ifdef _STATFS_F_FRSIZE
1680         tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize);
1681 #endif
1682         tprints("}");
1683 }
1684
1685 int
1686 sys_statfs(struct tcb *tcp)
1687 {
1688         if (entering(tcp)) {
1689                 printpath(tcp, tcp->u_arg[0]);
1690                 tprints(", ");
1691         } else {
1692                 printstatfs(tcp, tcp->u_arg[1]);
1693         }
1694         return 0;
1695 }
1696
1697 int
1698 sys_fstatfs(struct tcb *tcp)
1699 {
1700         if (entering(tcp)) {
1701                 printfd(tcp, tcp->u_arg[0]);
1702                 tprints(", ");
1703         } else {
1704                 printstatfs(tcp, tcp->u_arg[1]);
1705         }
1706         return 0;
1707 }
1708
1709 #if defined HAVE_STATFS64
1710 static void
1711 printstatfs64(struct tcb *tcp, long addr)
1712 {
1713         struct statfs64 statbuf;
1714
1715         if (syserror(tcp) || !verbose(tcp)) {
1716                 tprintf("%#lx", addr);
1717                 return;
1718         }
1719         if (umove(tcp, addr, &statbuf) < 0) {
1720                 tprints("{...}");
1721                 return;
1722         }
1723         tprintf("{f_type=%s, f_bsize=%llu, f_blocks=%llu, f_bfree=%llu, ",
1724                 sprintfstype(statbuf.f_type),
1725                 (unsigned long long)statbuf.f_bsize,
1726                 (unsigned long long)statbuf.f_blocks,
1727                 (unsigned long long)statbuf.f_bfree);
1728         tprintf("f_bavail=%llu, f_files=%llu, f_ffree=%llu, f_fsid={%d, %d}",
1729                 (unsigned long long)statbuf.f_bavail,
1730                 (unsigned long long)statbuf.f_files,
1731                 (unsigned long long)statbuf.f_ffree,
1732                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
1733         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
1734 #ifdef _STATFS_F_FRSIZE
1735         tprintf(", f_frsize=%llu", (unsigned long long)statbuf.f_frsize);
1736 #endif
1737 #ifdef _STATFS_F_FLAGS
1738         tprintf(", f_flags=%llu", (unsigned long long)statbuf.f_flags);
1739 #endif
1740         tprints("}");
1741 }
1742
1743 struct compat_statfs64 {
1744         uint32_t f_type;
1745         uint32_t f_bsize;
1746         uint64_t f_blocks;
1747         uint64_t f_bfree;
1748         uint64_t f_bavail;
1749         uint64_t f_files;
1750         uint64_t f_ffree;
1751         fsid_t f_fsid;
1752         uint32_t f_namelen;
1753         uint32_t f_frsize;
1754         uint32_t f_flags;
1755         uint32_t f_spare[4];
1756 }
1757 #if defined(X86_64) || defined(IA64)
1758   __attribute__ ((packed, aligned(4)))
1759 #endif
1760 ;
1761
1762 static void
1763 printcompat_statfs64(struct tcb *tcp, long addr)
1764 {
1765         struct compat_statfs64 statbuf;
1766
1767         if (syserror(tcp) || !verbose(tcp)) {
1768                 tprintf("%#lx", addr);
1769                 return;
1770         }
1771         if (umove(tcp, addr, &statbuf) < 0) {
1772                 tprints("{...}");
1773                 return;
1774         }
1775         tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%llu, f_bfree=%llu, ",
1776                 sprintfstype(statbuf.f_type),
1777                 (unsigned long)statbuf.f_bsize,
1778                 (unsigned long long)statbuf.f_blocks,
1779                 (unsigned long long)statbuf.f_bfree);
1780         tprintf("f_bavail=%llu, f_files=%llu, f_ffree=%llu, f_fsid={%d, %d}",
1781                 (unsigned long long)statbuf.f_bavail,
1782                 (unsigned long long)statbuf.f_files,
1783                 (unsigned long long)statbuf.f_ffree,
1784                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
1785         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
1786         tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize);
1787         tprintf(", f_flags=%lu}", (unsigned long)statbuf.f_frsize);
1788 }
1789
1790 int
1791 sys_statfs64(struct tcb *tcp)
1792 {
1793         if (entering(tcp)) {
1794                 printpath(tcp, tcp->u_arg[0]);
1795                 tprintf(", %lu, ", tcp->u_arg[1]);
1796         } else {
1797                 if (tcp->u_arg[1] == sizeof(struct statfs64))
1798                         printstatfs64(tcp, tcp->u_arg[2]);
1799                 else if (tcp->u_arg[1] == sizeof(struct compat_statfs64))
1800                         printcompat_statfs64(tcp, tcp->u_arg[2]);
1801                 else
1802                         tprints("{???}");
1803         }
1804         return 0;
1805 }
1806
1807 int
1808 sys_fstatfs64(struct tcb *tcp)
1809 {
1810         if (entering(tcp)) {
1811                 printfd(tcp, tcp->u_arg[0]);
1812                 tprintf(", %lu, ", tcp->u_arg[1]);
1813         } else {
1814                 if (tcp->u_arg[1] == sizeof(struct statfs64))
1815                         printstatfs64(tcp, tcp->u_arg[2]);
1816                 else if (tcp->u_arg[1] == sizeof(struct compat_statfs64))
1817                         printcompat_statfs64(tcp, tcp->u_arg[2]);
1818                 else
1819                         tprints("{???}");
1820         }
1821         return 0;
1822 }
1823 #endif
1824
1825 #if defined(ALPHA)
1826 int
1827 osf_statfs(struct tcb *tcp)
1828 {
1829         if (entering(tcp)) {
1830                 printpath(tcp, tcp->u_arg[0]);
1831                 tprints(", ");
1832         } else {
1833                 printstatfs(tcp, tcp->u_arg[1]);
1834                 tprintf(", %lu", tcp->u_arg[2]);
1835         }
1836         return 0;
1837 }
1838
1839 int
1840 osf_fstatfs(struct tcb *tcp)
1841 {
1842         if (entering(tcp)) {
1843                 tprintf("%lu, ", tcp->u_arg[0]);
1844         } else {
1845                 printstatfs(tcp, tcp->u_arg[1]);
1846                 tprintf(", %lu", tcp->u_arg[2]);
1847         }
1848         return 0;
1849 }
1850 #endif
1851
1852 /* directory */
1853 int
1854 sys_chdir(struct tcb *tcp)
1855 {
1856         if (entering(tcp)) {
1857                 printpath(tcp, tcp->u_arg[0]);
1858         }
1859         return 0;
1860 }
1861
1862 static int
1863 decode_mkdir(struct tcb *tcp, int offset)
1864 {
1865         if (entering(tcp)) {
1866                 printpath(tcp, tcp->u_arg[offset]);
1867                 tprintf(", %#lo", tcp->u_arg[offset + 1]);
1868         }
1869         return 0;
1870 }
1871
1872 int
1873 sys_mkdir(struct tcb *tcp)
1874 {
1875         return decode_mkdir(tcp, 0);
1876 }
1877
1878 int
1879 sys_mkdirat(struct tcb *tcp)
1880 {
1881         if (entering(tcp))
1882                 print_dirfd(tcp, tcp->u_arg[0]);
1883         return decode_mkdir(tcp, 1);
1884 }
1885
1886 int
1887 sys_link(struct tcb *tcp)
1888 {
1889         if (entering(tcp)) {
1890                 printpath(tcp, tcp->u_arg[0]);
1891                 tprints(", ");
1892                 printpath(tcp, tcp->u_arg[1]);
1893         }
1894         return 0;
1895 }
1896
1897 int
1898 sys_linkat(struct tcb *tcp)
1899 {
1900         if (entering(tcp)) {
1901                 print_dirfd(tcp, tcp->u_arg[0]);
1902                 printpath(tcp, tcp->u_arg[1]);
1903                 tprints(", ");
1904                 print_dirfd(tcp, tcp->u_arg[2]);
1905                 printpath(tcp, tcp->u_arg[3]);
1906                 tprints(", ");
1907                 printflags(at_flags, tcp->u_arg[4], "AT_???");
1908         }
1909         return 0;
1910 }
1911
1912 int
1913 sys_unlinkat(struct tcb *tcp)
1914 {
1915         if (entering(tcp)) {
1916                 print_dirfd(tcp, tcp->u_arg[0]);
1917                 printpath(tcp, tcp->u_arg[1]);
1918                 tprints(", ");
1919                 printflags(at_flags, tcp->u_arg[2], "AT_???");
1920         }
1921         return 0;
1922 }
1923
1924 int
1925 sys_symlinkat(struct tcb *tcp)
1926 {
1927         if (entering(tcp)) {
1928                 printpath(tcp, tcp->u_arg[0]);
1929                 tprints(", ");
1930                 print_dirfd(tcp, tcp->u_arg[1]);
1931                 printpath(tcp, tcp->u_arg[2]);
1932         }
1933         return 0;
1934 }
1935
1936 static int
1937 decode_readlink(struct tcb *tcp, int offset)
1938 {
1939         if (entering(tcp)) {
1940                 printpath(tcp, tcp->u_arg[offset]);
1941                 tprints(", ");
1942         } else {
1943                 if (syserror(tcp))
1944                         tprintf("%#lx", tcp->u_arg[offset + 1]);
1945                 else
1946                         /* Used to use printpathn(), but readlink
1947                          * neither includes NUL in the returned count,
1948                          * nor actually writes it into memory.
1949                          * printpathn() would decide on printing
1950                          * "..." continuation based on garbage
1951                          * past return buffer's end.
1952                          */
1953                         printstr(tcp, tcp->u_arg[offset + 1], tcp->u_rval);
1954                 tprintf(", %lu", tcp->u_arg[offset + 2]);
1955         }
1956         return 0;
1957 }
1958
1959 int
1960 sys_readlink(struct tcb *tcp)
1961 {
1962         return decode_readlink(tcp, 0);
1963 }
1964
1965 int
1966 sys_readlinkat(struct tcb *tcp)
1967 {
1968         if (entering(tcp))
1969                 print_dirfd(tcp, tcp->u_arg[0]);
1970         return decode_readlink(tcp, 1);
1971 }
1972
1973 int
1974 sys_renameat(struct tcb *tcp)
1975 {
1976         if (entering(tcp)) {
1977                 print_dirfd(tcp, tcp->u_arg[0]);
1978                 printpath(tcp, tcp->u_arg[1]);
1979                 tprints(", ");
1980                 print_dirfd(tcp, tcp->u_arg[2]);
1981                 printpath(tcp, tcp->u_arg[3]);
1982         }
1983         return 0;
1984 }
1985
1986 int
1987 sys_chown(struct tcb *tcp)
1988 {
1989         if (entering(tcp)) {
1990                 printpath(tcp, tcp->u_arg[0]);
1991                 printuid(", ", tcp->u_arg[1]);
1992                 printuid(", ", tcp->u_arg[2]);
1993         }
1994         return 0;
1995 }
1996
1997 int
1998 sys_fchownat(struct tcb *tcp)
1999 {
2000         if (entering(tcp)) {
2001                 print_dirfd(tcp, tcp->u_arg[0]);
2002                 printpath(tcp, tcp->u_arg[1]);
2003                 printuid(", ", tcp->u_arg[2]);
2004                 printuid(", ", tcp->u_arg[3]);
2005                 tprints(", ");
2006                 printflags(at_flags, tcp->u_arg[4], "AT_???");
2007         }
2008         return 0;
2009 }
2010
2011 int
2012 sys_fchown(struct tcb *tcp)
2013 {
2014         if (entering(tcp)) {
2015                 printfd(tcp, tcp->u_arg[0]);
2016                 printuid(", ", tcp->u_arg[1]);
2017                 printuid(", ", tcp->u_arg[2]);
2018         }
2019         return 0;
2020 }
2021
2022 static int
2023 decode_chmod(struct tcb *tcp, int offset)
2024 {
2025         if (entering(tcp)) {
2026                 printpath(tcp, tcp->u_arg[offset]);
2027                 tprintf(", %#lo", tcp->u_arg[offset + 1]);
2028         }
2029         return 0;
2030 }
2031
2032 int
2033 sys_chmod(struct tcb *tcp)
2034 {
2035         return decode_chmod(tcp, 0);
2036 }
2037
2038 int
2039 sys_fchmodat(struct tcb *tcp)
2040 {
2041         if (entering(tcp))
2042                 print_dirfd(tcp, tcp->u_arg[0]);
2043         return decode_chmod(tcp, 1);
2044 }
2045
2046 int
2047 sys_fchmod(struct tcb *tcp)
2048 {
2049         if (entering(tcp)) {
2050                 printfd(tcp, tcp->u_arg[0]);
2051                 tprintf(", %#lo", tcp->u_arg[1]);
2052         }
2053         return 0;
2054 }
2055
2056 #ifdef ALPHA
2057 int
2058 sys_osf_utimes(struct tcb *tcp)
2059 {
2060         if (entering(tcp)) {
2061                 printpath(tcp, tcp->u_arg[0]);
2062                 tprints(", ");
2063                 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32,  0);
2064         }
2065         return 0;
2066 }
2067 #endif
2068
2069 static int
2070 decode_utimes(struct tcb *tcp, int offset, int special)
2071 {
2072         if (entering(tcp)) {
2073                 printpath(tcp, tcp->u_arg[offset]);
2074                 tprints(", ");
2075                 if (tcp->u_arg[offset + 1] == 0)
2076                         tprints("NULL");
2077                 else {
2078                         tprints("{");
2079                         printtv_bitness(tcp, tcp->u_arg[offset + 1],
2080                                         BITNESS_CURRENT, special);
2081                         tprints(", ");
2082                         printtv_bitness(tcp, tcp->u_arg[offset + 1]
2083                                         + sizeof(struct timeval),
2084                                         BITNESS_CURRENT, special);
2085                         tprints("}");
2086                 }
2087         }
2088         return 0;
2089 }
2090
2091 int
2092 sys_utimes(struct tcb *tcp)
2093 {
2094         return decode_utimes(tcp, 0, 0);
2095 }
2096
2097 int
2098 sys_futimesat(struct tcb *tcp)
2099 {
2100         if (entering(tcp))
2101                 print_dirfd(tcp, tcp->u_arg[0]);
2102         return decode_utimes(tcp, 1, 0);
2103 }
2104
2105 int
2106 sys_utimensat(struct tcb *tcp)
2107 {
2108         if (entering(tcp)) {
2109                 print_dirfd(tcp, tcp->u_arg[0]);
2110                 decode_utimes(tcp, 1, 1);
2111                 tprints(", ");
2112                 printflags(at_flags, tcp->u_arg[3], "AT_???");
2113         }
2114         return 0;
2115 }
2116
2117 int
2118 sys_utime(struct tcb *tcp)
2119 {
2120         union {
2121                 long utl[2];
2122                 int uti[2];
2123                 long paranoia_for_huge_wordsize[4];
2124         } u;
2125         unsigned wordsize;
2126
2127         if (entering(tcp)) {
2128                 printpath(tcp, tcp->u_arg[0]);
2129                 tprints(", ");
2130
2131                 wordsize = current_wordsize;
2132                 if (!tcp->u_arg[1])
2133                         tprints("NULL");
2134                 else if (!verbose(tcp))
2135                         tprintf("%#lx", tcp->u_arg[1]);
2136                 else if (umoven(tcp, tcp->u_arg[1], 2 * wordsize, (char *) &u) < 0)
2137                         tprints("[?, ?]");
2138                 else if (wordsize == sizeof u.utl[0]) {
2139                         tprintf("[%s,", sprinttime(u.utl[0]));
2140                         tprintf(" %s]", sprinttime(u.utl[1]));
2141                 }
2142                 else if (wordsize == sizeof u.uti[0]) {
2143                         tprintf("[%s,", sprinttime(u.uti[0]));
2144                         tprintf(" %s]", sprinttime(u.uti[1]));
2145                 }
2146                 else
2147                         tprintf("<decode error: unsupported wordsize %d>",
2148                                 wordsize);
2149         }
2150         return 0;
2151 }
2152
2153 static int
2154 decode_mknod(struct tcb *tcp, int offset)
2155 {
2156         int mode = tcp->u_arg[offset + 1];
2157
2158         if (entering(tcp)) {
2159                 printpath(tcp, tcp->u_arg[offset]);
2160                 tprintf(", %s", sprintmode(mode));
2161                 switch (mode & S_IFMT) {
2162                 case S_IFCHR:
2163                 case S_IFBLK:
2164 #if defined(SPARC) || defined(SPARC64)
2165                         if (current_personality == 1)
2166                                 tprintf(", makedev(%lu, %lu)",
2167                                 (unsigned long) ((tcp->u_arg[offset + 2] >> 18) & 0x3fff),
2168                                 (unsigned long) (tcp->u_arg[offset + 2] & 0x3ffff));
2169                         else
2170 #endif
2171                                 tprintf(", makedev(%lu, %lu)",
2172                                 (unsigned long) major(tcp->u_arg[offset + 2]),
2173                                 (unsigned long) minor(tcp->u_arg[offset + 2]));
2174                         break;
2175                 default:
2176                         break;
2177                 }
2178         }
2179         return 0;
2180 }
2181
2182 int
2183 sys_mknod(struct tcb *tcp)
2184 {
2185         return decode_mknod(tcp, 0);
2186 }
2187
2188 int
2189 sys_mknodat(struct tcb *tcp)
2190 {
2191         if (entering(tcp))
2192                 print_dirfd(tcp, tcp->u_arg[0]);
2193         return decode_mknod(tcp, 1);
2194 }
2195
2196 static void
2197 print_old_dirent(struct tcb *tcp, long addr)
2198 {
2199 #ifdef SH64
2200         typedef struct kernel_dirent old_dirent_t;
2201 #else
2202         typedef struct {
2203                 uint32_t        d_ino;
2204                 uint32_t        d_off;
2205                 unsigned short  d_reclen;
2206                 char            d_name[1];
2207         } old_dirent_t;
2208 #endif
2209         old_dirent_t d;
2210
2211         if (!verbose(tcp) || umove(tcp, addr, &d) < 0) {
2212                 tprintf("%#lx", addr);
2213                 return;
2214         }
2215
2216         tprintf("{d_ino=%lu, d_off=%lu, d_reclen=%u, d_name=\"",
2217                 (unsigned long) d.d_ino, (unsigned long) d.d_off, d.d_reclen);
2218         if (d.d_reclen > 256)
2219                 d.d_reclen = 256;
2220         printpathn(tcp, addr + offsetof(old_dirent_t, d_name), d.d_reclen);
2221         tprints("\"}");
2222 }
2223
2224 int
2225 sys_readdir(struct tcb *tcp)
2226 {
2227         if (entering(tcp)) {
2228                 printfd(tcp, tcp->u_arg[0]);
2229                 tprints(", ");
2230         } else {
2231                 if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
2232                         tprintf("%#lx", tcp->u_arg[1]);
2233                 else
2234                         print_old_dirent(tcp, tcp->u_arg[1]);
2235                 /* Not much point in printing this out, it is always 1. */
2236                 if (tcp->u_arg[2] != 1)
2237                         tprintf(", %lu", tcp->u_arg[2]);
2238         }
2239         return 0;
2240 }
2241
2242 static const struct xlat direnttypes[] = {
2243         XLAT(DT_UNKNOWN),
2244         XLAT(DT_FIFO),
2245         XLAT(DT_CHR),
2246         XLAT(DT_DIR),
2247         XLAT(DT_BLK),
2248         XLAT(DT_REG),
2249         XLAT(DT_LNK),
2250         XLAT(DT_SOCK),
2251         XLAT(DT_WHT),
2252         XLAT_END
2253 };
2254
2255 int
2256 sys_getdents(struct tcb *tcp)
2257 {
2258         int i, len, dents = 0;
2259         char *buf;
2260
2261         if (entering(tcp)) {
2262                 printfd(tcp, tcp->u_arg[0]);
2263                 tprints(", ");
2264                 return 0;
2265         }
2266         if (syserror(tcp) || !verbose(tcp)) {
2267                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2268                 return 0;
2269         }
2270         len = tcp->u_rval;
2271         /* Beware of insanely large or negative values in tcp->u_rval */
2272         if (tcp->u_rval > 1024*1024)
2273                 len = 1024*1024;
2274         if (tcp->u_rval < 0)
2275                 len = 0;
2276         buf = len ? malloc(len) : NULL;
2277         if (len && !buf)
2278                 die_out_of_memory();
2279         if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
2280                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2281                 free(buf);
2282                 return 0;
2283         }
2284         if (!abbrev(tcp))
2285                 tprints("{");
2286         for (i = 0; i < len;) {
2287                 struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
2288                 if (!abbrev(tcp)) {
2289                         tprintf("%s{d_ino=%lu, d_off=%lu, ",
2290                                 i ? " " : "", d->d_ino, d->d_off);
2291                         tprintf("d_reclen=%u, d_name=\"%s\", d_type=",
2292                                 d->d_reclen, d->d_name);
2293                         printxval(direnttypes, buf[i + d->d_reclen - 1], "DT_???");
2294                         tprints("}");
2295                 }
2296                 if (!d->d_reclen) {
2297                         tprints("/* d_reclen == 0, problem here */");
2298                         break;
2299                 }
2300                 i += d->d_reclen;
2301                 dents++;
2302         }
2303         if (!abbrev(tcp))
2304                 tprints("}");
2305         else
2306                 tprintf("/* %u entries */", dents);
2307         tprintf(", %lu", tcp->u_arg[2]);
2308         free(buf);
2309         return 0;
2310 }
2311
2312 int
2313 sys_getdents64(struct tcb *tcp)
2314 {
2315         int i, len, dents = 0;
2316         char *buf;
2317
2318         if (entering(tcp)) {
2319                 printfd(tcp, tcp->u_arg[0]);
2320                 tprints(", ");
2321                 return 0;
2322         }
2323         if (syserror(tcp) || !verbose(tcp)) {
2324                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2325                 return 0;
2326         }
2327
2328         len = tcp->u_rval;
2329         /* Beware of insanely large or negative tcp->u_rval */
2330         if (tcp->u_rval > 1024*1024)
2331                 len = 1024*1024;
2332         if (tcp->u_rval < 0)
2333                 len = 0;
2334         buf = len ? malloc(len) : NULL;
2335         if (len && !buf)
2336                 die_out_of_memory();
2337
2338         if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
2339                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2340                 free(buf);
2341                 return 0;
2342         }
2343         if (!abbrev(tcp))
2344                 tprints("{");
2345         for (i = 0; i < len;) {
2346                 struct dirent64 *d = (struct dirent64 *) &buf[i];
2347                 if (!abbrev(tcp)) {
2348                         tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64 ", ",
2349                                 i ? " " : "",
2350                                 d->d_ino,
2351                                 d->d_off);
2352                         tprints("d_type=");
2353                         printxval(direnttypes, d->d_type, "DT_???");
2354                         tprints(", ");
2355                         tprintf("d_reclen=%u, d_name=\"%s\"}",
2356                                 d->d_reclen, d->d_name);
2357                 }
2358                 if (!d->d_reclen) {
2359                         tprints("/* d_reclen == 0, problem here */");
2360                         break;
2361                 }
2362                 i += d->d_reclen;
2363                 dents++;
2364         }
2365         if (!abbrev(tcp))
2366                 tprints("}");
2367         else
2368                 tprintf("/* %u entries */", dents);
2369         tprintf(", %lu", tcp->u_arg[2]);
2370         free(buf);
2371         return 0;
2372 }
2373
2374 int
2375 sys_getcwd(struct tcb *tcp)
2376 {
2377         if (exiting(tcp)) {
2378                 if (syserror(tcp))
2379                         tprintf("%#lx", tcp->u_arg[0]);
2380                 else
2381                         printpathn(tcp, tcp->u_arg[0], tcp->u_rval - 1);
2382                 tprintf(", %lu", tcp->u_arg[1]);
2383         }
2384         return 0;
2385 }
2386
2387 #ifdef HAVE_SYS_ASYNCH_H
2388
2389 int
2390 sys_aioread(struct tcb *tcp)
2391 {
2392         struct aio_result_t res;
2393
2394         if (entering(tcp)) {
2395                 tprintf("%lu, ", tcp->u_arg[0]);
2396         } else {
2397                 if (syserror(tcp))
2398                         tprintf("%#lx", tcp->u_arg[1]);
2399                 else
2400                         printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
2401                 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
2402                 printxval(whence, tcp->u_arg[4], "L_???");
2403                 if (syserror(tcp) || tcp->u_arg[5] == 0
2404                     || umove(tcp, tcp->u_arg[5], &res) < 0)
2405                         tprintf(", %#lx", tcp->u_arg[5]);
2406                 else
2407                         tprintf(", {aio_return %d aio_errno %d}",
2408                                 res.aio_return, res.aio_errno);
2409         }
2410         return 0;
2411 }
2412
2413 int
2414 sys_aiowrite(struct tcb *tcp)
2415 {
2416         struct aio_result_t res;
2417
2418         if (entering(tcp)) {
2419                 tprintf("%lu, ", tcp->u_arg[0]);
2420                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
2421                 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
2422                 printxval(whence, tcp->u_arg[4], "L_???");
2423         }
2424         else {
2425                 if (tcp->u_arg[5] == 0)
2426                         tprints(", NULL");
2427                 else if (syserror(tcp)
2428                     || umove(tcp, tcp->u_arg[5], &res) < 0)
2429                         tprintf(", %#lx", tcp->u_arg[5]);
2430                 else
2431                         tprintf(", {aio_return %d aio_errno %d}",
2432                                 res.aio_return, res.aio_errno);
2433         }
2434         return 0;
2435 }
2436
2437 int
2438 sys_aiowait(struct tcb *tcp)
2439 {
2440         if (entering(tcp))
2441                 printtv(tcp, tcp->u_arg[0]);
2442         return 0;
2443 }
2444
2445 int
2446 sys_aiocancel(struct tcb *tcp)
2447 {
2448         struct aio_result_t res;
2449
2450         if (exiting(tcp)) {
2451                 if (tcp->u_arg[0] == 0)
2452                         tprints("NULL");
2453                 else if (syserror(tcp)
2454                     || umove(tcp, tcp->u_arg[0], &res) < 0)
2455                         tprintf("%#lx", tcp->u_arg[0]);
2456                 else
2457                         tprintf("{aio_return %d aio_errno %d}",
2458                                 res.aio_return, res.aio_errno);
2459         }
2460         return 0;
2461 }
2462
2463 #endif /* HAVE_SYS_ASYNCH_H */
2464
2465 static const struct xlat xattrflags[] = {
2466 #ifdef XATTR_CREATE
2467         XLAT(XATTR_CREATE),
2468         XLAT(XATTR_REPLACE),
2469 #endif
2470         XLAT_END
2471 };
2472
2473 static void
2474 print_xattr_val(struct tcb *tcp, int failed,
2475                 unsigned long arg,
2476                 unsigned long insize,
2477                 unsigned long size)
2478 {
2479         if (insize == 0)
2480                 failed = 1;
2481         if (!failed) {
2482                 unsigned long capacity = 4 * size + 1;
2483                 unsigned char *buf = (capacity < size) ? NULL : malloc(capacity);
2484                 if (buf == NULL || /* probably a bogus size argument */
2485                         umoven(tcp, arg, size, (char *) &buf[3 * size]) < 0) {
2486                         failed = 1;
2487                 }
2488                 else {
2489                         unsigned char *out = buf;
2490                         unsigned char *in = &buf[3 * size];
2491                         size_t i;
2492                         for (i = 0; i < size; ++i) {
2493                                 if (in[i] >= ' ' && in[i] <= 0x7e)
2494                                         *out++ = in[i];
2495                                 else {
2496 #define tohex(n) "0123456789abcdef"[n]
2497                                         *out++ = '\\';
2498                                         *out++ = 'x';
2499                                         *out++ = tohex(in[i] / 16);
2500                                         *out++ = tohex(in[i] % 16);
2501                                 }
2502                         }
2503                         /* Don't print terminating NUL if there is one.  */
2504                         if (i > 0 && in[i - 1] == '\0')
2505                                 out -= 4;
2506                         *out = '\0';
2507                         tprintf(", \"%s\", %ld", buf, insize);
2508                 }
2509                 free(buf);
2510         }
2511         if (failed)
2512                 tprintf(", 0x%lx, %ld", arg, insize);
2513 }
2514
2515 int
2516 sys_setxattr(struct tcb *tcp)
2517 {
2518         if (entering(tcp)) {
2519                 printpath(tcp, tcp->u_arg[0]);
2520                 tprints(", ");
2521                 printstr(tcp, tcp->u_arg[1], -1);
2522                 print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
2523                 tprints(", ");
2524                 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
2525         }
2526         return 0;
2527 }
2528
2529 int
2530 sys_fsetxattr(struct tcb *tcp)
2531 {
2532         if (entering(tcp)) {
2533                 printfd(tcp, tcp->u_arg[0]);
2534                 tprints(", ");
2535                 printstr(tcp, tcp->u_arg[1], -1);
2536                 print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
2537                 tprints(", ");
2538                 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
2539         }
2540         return 0;
2541 }
2542
2543 int
2544 sys_getxattr(struct tcb *tcp)
2545 {
2546         if (entering(tcp)) {
2547                 printpath(tcp, tcp->u_arg[0]);
2548                 tprints(", ");
2549                 printstr(tcp, tcp->u_arg[1], -1);
2550         } else {
2551                 print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
2552                                 tcp->u_rval);
2553         }
2554         return 0;
2555 }
2556
2557 int
2558 sys_fgetxattr(struct tcb *tcp)
2559 {
2560         if (entering(tcp)) {
2561                 printfd(tcp, tcp->u_arg[0]);
2562                 tprints(", ");
2563                 printstr(tcp, tcp->u_arg[1], -1);
2564         } else {
2565                 print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
2566                                 tcp->u_rval);
2567         }
2568         return 0;
2569 }
2570
2571 static void
2572 print_xattr_list(struct tcb *tcp, unsigned long addr, unsigned long size)
2573 {
2574         if (syserror(tcp)) {
2575                 tprintf("%#lx", addr);
2576         } else {
2577                 if (!addr) {
2578                         tprints("NULL");
2579                 } else {
2580                         unsigned long len =
2581                                 (size < tcp->u_rval) ? size : tcp->u_rval;
2582                         printstr(tcp, addr, len);
2583                 }
2584         }
2585         tprintf(", %lu", size);
2586 }
2587
2588 int
2589 sys_listxattr(struct tcb *tcp)
2590 {
2591         if (entering(tcp)) {
2592                 printpath(tcp, tcp->u_arg[0]);
2593                 tprints(", ");
2594         } else {
2595                 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]);
2596         }
2597         return 0;
2598 }
2599
2600 int
2601 sys_flistxattr(struct tcb *tcp)
2602 {
2603         if (entering(tcp)) {
2604                 printfd(tcp, tcp->u_arg[0]);
2605                 tprints(", ");
2606         } else {
2607                 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]);
2608         }
2609         return 0;
2610 }
2611
2612 int
2613 sys_removexattr(struct tcb *tcp)
2614 {
2615         if (entering(tcp)) {
2616                 printpath(tcp, tcp->u_arg[0]);
2617                 tprints(", ");
2618                 printstr(tcp, tcp->u_arg[1], -1);
2619         }
2620         return 0;
2621 }
2622
2623 int
2624 sys_fremovexattr(struct tcb *tcp)
2625 {
2626         if (entering(tcp)) {
2627                 printfd(tcp, tcp->u_arg[0]);
2628                 tprints(", ");
2629                 printstr(tcp, tcp->u_arg[1], -1);
2630         }
2631         return 0;
2632 }
2633
2634 static const struct xlat advise[] = {
2635         XLAT(POSIX_FADV_NORMAL),
2636         XLAT(POSIX_FADV_RANDOM),
2637         XLAT(POSIX_FADV_SEQUENTIAL),
2638         XLAT(POSIX_FADV_WILLNEED),
2639         XLAT(POSIX_FADV_DONTNEED),
2640         XLAT(POSIX_FADV_NOREUSE),
2641         XLAT_END
2642 };
2643
2644 int
2645 sys_fadvise64(struct tcb *tcp)
2646 {
2647         if (entering(tcp)) {
2648                 int argn;
2649                 printfd(tcp, tcp->u_arg[0]);
2650                 argn = printllval(tcp, ", %lld", 1);
2651                 tprintf(", %ld, ", tcp->u_arg[argn++]);
2652                 printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???");
2653         }
2654         return 0;
2655 }
2656
2657 int
2658 sys_fadvise64_64(struct tcb *tcp)
2659 {
2660         if (entering(tcp)) {
2661                 int argn;
2662                 printfd(tcp, tcp->u_arg[0]);
2663                 argn = printllval(tcp, ", %lld, ", 1);
2664                 argn = printllval(tcp, "%lld, ", argn);
2665 #if defined __ARM_EABI__ || defined AARCH64 || defined POWERPC || defined XTENSA
2666                 printxval(advise, tcp->u_arg[1], "POSIX_FADV_???");
2667 #else
2668                 printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???");
2669 #endif
2670         }
2671         return 0;
2672 }
2673
2674 static const struct xlat sync_file_range_flags[] = {
2675         XLAT(SYNC_FILE_RANGE_WAIT_BEFORE),
2676         XLAT(SYNC_FILE_RANGE_WRITE),
2677         XLAT(SYNC_FILE_RANGE_WAIT_AFTER),
2678         XLAT_END
2679 };
2680
2681 int
2682 sys_sync_file_range(struct tcb *tcp)
2683 {
2684         if (entering(tcp)) {
2685                 int argn;
2686                 printfd(tcp, tcp->u_arg[0]);
2687                 argn = printllval(tcp, ", %lld, ", 1);
2688                 argn = printllval(tcp, "%lld, ", argn);
2689                 printflags(sync_file_range_flags, tcp->u_arg[argn],
2690                            "SYNC_FILE_RANGE_???");
2691         }
2692         return 0;
2693 }
2694
2695 int
2696 sys_sync_file_range2(struct tcb *tcp)
2697 {
2698         if (entering(tcp)) {
2699                 int argn;
2700                 printfd(tcp, tcp->u_arg[0]);
2701                 printflags(sync_file_range_flags, 1,
2702                            "SYNC_FILE_RANGE_???");
2703                 argn = printllval(tcp, ", %lld, ", 2);
2704                 argn = printllval(tcp, "%lld, ", argn);
2705         }
2706         return 0;
2707 }
2708
2709 int
2710 sys_fallocate(struct tcb *tcp)
2711 {
2712         if (entering(tcp)) {
2713                 int argn;
2714                 printfd(tcp, tcp->u_arg[0]);            /* fd */
2715                 tprintf(", %#lo, ", tcp->u_arg[1]);     /* mode */
2716                 argn = printllval(tcp, "%llu, ", 2);    /* offset */
2717                 printllval(tcp, "%llu", argn);          /* len */
2718         }
2719         return 0;
2720 }
2721
2722 #ifndef SWAP_FLAG_PREFER
2723 # define SWAP_FLAG_PREFER 0x8000
2724 #endif
2725 #ifndef SWAP_FLAG_DISCARD
2726 # define SWAP_FLAG_DISCARD 0x10000
2727 #endif
2728 static const struct xlat swap_flags[] = {
2729         XLAT(SWAP_FLAG_PREFER),
2730         XLAT(SWAP_FLAG_DISCARD),
2731         XLAT_END
2732 };
2733
2734 int
2735 sys_swapon(struct tcb *tcp)
2736 {
2737         if (entering(tcp)) {
2738                 int flags = tcp->u_arg[1];
2739                 printpath(tcp, tcp->u_arg[0]);
2740                 tprints(", ");
2741                 printflags(swap_flags, flags & ~SWAP_FLAG_PRIO_MASK,
2742                         "SWAP_FLAG_???");
2743                 if (flags & SWAP_FLAG_PREFER)
2744                         tprintf("|%d", flags & SWAP_FLAG_PRIO_MASK);
2745         }
2746         return 0;
2747 }