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