blob: e4dd33b6aa0b6d91048bceff1a162314ddebf3d3 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
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>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00006 * 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.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000029 */
30
31#include "defs.h"
Dmitry V. Levin88293652012-03-09 21:02:19 +000032#include <sys/swap.h>
Roland McGrathc531e572008-08-01 01:13:10 +000033
Denys Vlasenko9472a272013-02-12 11:43:46 +010034#if defined(SPARC) || defined(SPARC64)
Wichert Akkermandacfb6e1999-06-03 14:21:07 +000035struct stat {
36 unsigned short st_dev;
37 unsigned int st_ino;
38 unsigned short st_mode;
39 short st_nlink;
40 unsigned short st_uid;
41 unsigned short st_gid;
42 unsigned short st_rdev;
43 unsigned int st_size;
44 int st_atime;
45 unsigned int __unused1;
46 int st_mtime;
47 unsigned int __unused2;
48 int st_ctime;
49 unsigned int __unused3;
50 int st_blksize;
51 int st_blocks;
52 unsigned int __unused4[2];
53};
Denys Vlasenko84703742012-02-25 02:38:52 +010054# if defined(SPARC64)
Roland McGrath6d1a65c2004-07-12 07:44:08 +000055struct stat_sparc64 {
56 unsigned int st_dev;
57 unsigned long st_ino;
58 unsigned int st_mode;
59 unsigned int st_nlink;
60 unsigned int st_uid;
61 unsigned int st_gid;
62 unsigned int st_rdev;
63 long st_size;
64 long st_atime;
65 long st_mtime;
66 long st_ctime;
67 long st_blksize;
68 long st_blocks;
69 unsigned long __unused4[2];
70};
Denys Vlasenko84703742012-02-25 02:38:52 +010071# endif /* SPARC64 */
72# define stat kernel_stat
73# include <asm/stat.h>
74# undef stat
H.J. Lu35be5812012-04-16 13:00:01 +020075#elif defined(X32)
76struct stat {
77 unsigned long long st_dev;
78 unsigned long long st_ino;
79 unsigned long long st_nlink;
80
81 unsigned int st_mode;
82 unsigned int st_uid;
83 unsigned int st_gid;
84 unsigned int __pad0;
85 unsigned long long st_rdev;
86 long long st_size;
87 long long st_blksize;
88 long long st_blocks;
89
90 unsigned long long st_atime;
91 unsigned long long st_atime_nsec;
92 unsigned long long st_mtime;
93 unsigned long long st_mtime_nsec;
94 unsigned long long st_ctime;
95 unsigned long long st_ctime_nsec;
96 long long __unused[3];
97};
H.J. Lu085e4282012-04-17 11:05:04 -070098
99struct stat64 {
100 unsigned long long st_dev;
101 unsigned char __pad0[4];
102 unsigned long __st_ino;
103 unsigned int st_mode;
104 unsigned int st_nlink;
105 unsigned long st_uid;
106 unsigned long st_gid;
107 unsigned long long st_rdev;
108 unsigned char __pad3[4];
109 long long st_size;
110 unsigned long st_blksize;
111 unsigned long long st_blocks;
112 unsigned long st_atime;
113 unsigned long st_atime_nsec;
114 unsigned long st_mtime;
115 unsigned int st_mtime_nsec;
116 unsigned long st_ctime;
117 unsigned long st_ctime_nsec;
118 unsigned long long st_ino;
Dmitry V. Levin0eeda2c2013-05-01 16:37:08 +0000119} __attribute__((packed));
120# define HAVE_STAT64 1
Dmitry V. Levinbd2e28a2013-05-01 15:14:25 +0000121
122struct __old_kernel_stat {
123 unsigned short st_dev;
124 unsigned short st_ino;
125 unsigned short st_mode;
126 unsigned short st_nlink;
127 unsigned short st_uid;
128 unsigned short st_gid;
129 unsigned short st_rdev;
130 unsigned int st_size;
131 unsigned int st_atime;
132 unsigned int st_mtime;
133 unsigned int st_ctime;
134};
Denys Vlasenko84703742012-02-25 02:38:52 +0100135#else
136# undef dev_t
137# undef ino_t
138# undef mode_t
139# undef nlink_t
140# undef uid_t
141# undef gid_t
142# undef off_t
143# undef loff_t
Denys Vlasenko84703742012-02-25 02:38:52 +0100144# define dev_t __kernel_dev_t
145# define ino_t __kernel_ino_t
146# define mode_t __kernel_mode_t
147# define nlink_t __kernel_nlink_t
148# define uid_t __kernel_uid_t
149# define gid_t __kernel_gid_t
150# define off_t __kernel_off_t
151# define loff_t __kernel_loff_t
Wichert Akkermana6013701999-07-08 14:00:58 +0000152
Denys Vlasenko84703742012-02-25 02:38:52 +0100153# include <asm/stat.h>
Wichert Akkermana6013701999-07-08 14:00:58 +0000154
Denys Vlasenko84703742012-02-25 02:38:52 +0100155# undef dev_t
156# undef ino_t
157# undef mode_t
158# undef nlink_t
159# undef uid_t
160# undef gid_t
161# undef off_t
162# undef loff_t
Denys Vlasenko84703742012-02-25 02:38:52 +0100163# define dev_t dev_t
164# define ino_t ino_t
165# define mode_t mode_t
166# define nlink_t nlink_t
167# define uid_t uid_t
168# define gid_t gid_t
169# define off_t off_t
170# define loff_t loff_t
171#endif
172
Denys Vlasenko84703742012-02-25 02:38:52 +0100173#define stat libc_stat
174#define stat64 libc_stat64
175#include <sys/stat.h>
176#undef stat
177#undef stat64
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +0100178/* These might be macros. */
Denys Vlasenko84703742012-02-25 02:38:52 +0100179#undef st_atime
180#undef st_mtime
181#undef st_ctime
Wichert Akkermand4d8e921999-04-18 23:30:29 +0000182
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000183#include <fcntl.h>
Roland McGrath186c5ac2002-12-15 23:58:23 +0000184#ifdef HAVE_LINUX_XATTR_H
Denys Vlasenko84703742012-02-25 02:38:52 +0100185# include <linux/xattr.h>
Denys Vlasenkoed720fd2012-02-25 02:24:03 +0100186#else
Denys Vlasenko84703742012-02-25 02:38:52 +0100187# define XATTR_CREATE 1
188# define XATTR_REPLACE 2
Roland McGrath186c5ac2002-12-15 23:58:23 +0000189#endif
190
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000191#ifdef MAJOR_IN_SYSMACROS
Denys Vlasenko84703742012-02-25 02:38:52 +0100192# include <sys/sysmacros.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000193#endif
194
195#ifdef MAJOR_IN_MKDEV
Denys Vlasenko84703742012-02-25 02:38:52 +0100196# include <sys/mkdev.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000197#endif
198
Dmitry V. Levin63ebcfc2014-04-26 15:35:02 +0000199#ifdef O_LARGEFILE
200# if O_LARGEFILE == 0 /* biarch platforms in 64-bit mode */
201# undef O_LARGEFILE
202# ifdef SPARC64
203# define O_LARGEFILE 0x40000
204# elif defined X86_64 || defined S390X
205# define O_LARGEFILE 0100000
206# endif
207# endif
208#endif
209
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000210#include "xlat/open_access_modes.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000211#include "xlat/open_mode_flags.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000212
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000213#ifndef AT_FDCWD
214# define AT_FDCWD -100
215#endif
216
Denys Vlasenkoe740fd32009-04-16 12:06:16 +0000217/* The fd is an "int", so when decoding x86 on x86_64, we need to force sign
218 * extension to get the right value. We do this by declaring fd as int here.
219 */
Dmitry V. Levin99db95d2014-02-05 04:13:18 +0000220void
Dmitry V. Levin31382132011-03-04 05:08:02 +0300221print_dirfd(struct tcb *tcp, int fd)
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000222{
223 if (fd == AT_FDCWD)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200224 tprints("AT_FDCWD, ");
Denys Vlasenko7b609d52011-06-22 14:32:43 +0200225 else {
Dmitry V. Levin31382132011-03-04 05:08:02 +0300226 printfd(tcp, fd);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200227 tprints(", ");
Dmitry V. Levin31382132011-03-04 05:08:02 +0300228 }
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000229}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000230
Dmitry V. Levin9b5b67e2007-01-11 23:19:55 +0000231/*
232 * low bits of the open(2) flags define access mode,
233 * other bits are real flags.
234 */
Denys Vlasenkoeedaac72009-03-10 20:41:58 +0000235const char *
Elliott Hughes22e34b92014-09-23 19:09:50 -0700236sprint_open_modes(int flags)
Dmitry V. Levin9b5b67e2007-01-11 23:19:55 +0000237{
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100238 static char outstr[(1 + ARRAY_SIZE(open_mode_flags)) * sizeof("O_LARGEFILE")];
Denys Vlasenkoeedaac72009-03-10 20:41:58 +0000239 char *p;
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100240 char sep;
Denys Vlasenkoeedaac72009-03-10 20:41:58 +0000241 const char *str;
242 const struct xlat *x;
Dmitry V. Levin9b5b67e2007-01-11 23:19:55 +0000243
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100244 sep = ' ';
245 p = stpcpy(outstr, "flags");
Denys Vlasenkoeedaac72009-03-10 20:41:58 +0000246 str = xlookup(open_access_modes, flags & 3);
247 if (str) {
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100248 *p++ = sep;
Denys Vlasenko52845572011-08-31 12:07:38 +0200249 p = stpcpy(p, str);
Dmitry V. Levin9b5b67e2007-01-11 23:19:55 +0000250 flags &= ~3;
251 if (!flags)
Denys Vlasenkoeedaac72009-03-10 20:41:58 +0000252 return outstr;
253 sep = '|';
Dmitry V. Levin9b5b67e2007-01-11 23:19:55 +0000254 }
Denys Vlasenkoeedaac72009-03-10 20:41:58 +0000255
256 for (x = open_mode_flags; x->str; x++) {
257 if ((flags & x->val) == x->val) {
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100258 *p++ = sep;
Denys Vlasenko52845572011-08-31 12:07:38 +0200259 p = stpcpy(p, x->str);
Denys Vlasenkoeedaac72009-03-10 20:41:58 +0000260 flags &= ~x->val;
261 if (!flags)
262 return outstr;
263 sep = '|';
264 }
265 }
266 /* flags is still nonzero */
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100267 *p++ = sep;
Denys Vlasenkoeedaac72009-03-10 20:41:58 +0000268 sprintf(p, "%#x", flags);
269 return outstr;
270}
271
272void
Elliott Hughes22e34b92014-09-23 19:09:50 -0700273tprint_open_modes(int flags)
Denys Vlasenkoeedaac72009-03-10 20:41:58 +0000274{
Denys Vlasenko5940e652011-09-01 09:55:05 +0200275 tprints(sprint_open_modes(flags) + sizeof("flags"));
Dmitry V. Levin9b5b67e2007-01-11 23:19:55 +0000276}
277
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000278static int
279decode_open(struct tcb *tcp, int offset)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000280{
281 if (entering(tcp)) {
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000282 printpath(tcp, tcp->u_arg[offset]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200283 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000284 /* flags */
Denys Vlasenkoeedaac72009-03-10 20:41:58 +0000285 tprint_open_modes(tcp->u_arg[offset + 1]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000286 if (tcp->u_arg[offset + 1] & O_CREAT) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000287 /* mode */
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000288 tprintf(", %#lo", tcp->u_arg[offset + 2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000289 }
290 }
Zubin Mithra64aa1b12014-06-04 08:30:41 +0530291 return RVAL_FD;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000292}
293
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000294int
295sys_open(struct tcb *tcp)
296{
297 return decode_open(tcp, 0);
298}
299
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000300int
301sys_openat(struct tcb *tcp)
302{
303 if (entering(tcp))
Dmitry V. Levin31382132011-03-04 05:08:02 +0300304 print_dirfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000305 return decode_open(tcp, 1);
306}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000307
Denys Vlasenko9472a272013-02-12 11:43:46 +0100308#if defined(SPARC) || defined(SPARC64)
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000309#include "xlat/openmodessol.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000310
311int
Denys Vlasenko1d632462009-04-14 12:51:00 +0000312solaris_open(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000313{
314 if (entering(tcp)) {
315 printpath(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200316 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000317 /* flags */
Roland McGrathb2dee132005-06-01 19:02:36 +0000318 printflags(openmodessol, tcp->u_arg[1] + 1, "O_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000319 if (tcp->u_arg[1] & 0x100) {
320 /* mode */
321 tprintf(", %#lo", tcp->u_arg[2]);
322 }
323 }
324 return 0;
325}
326
327#endif
328
329int
Denys Vlasenko1d632462009-04-14 12:51:00 +0000330sys_creat(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000331{
332 if (entering(tcp)) {
333 printpath(tcp, tcp->u_arg[0]);
334 tprintf(", %#lo", tcp->u_arg[1]);
335 }
Zubin Mithra64aa1b12014-06-04 08:30:41 +0530336 return RVAL_FD;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000337}
338
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000339#include "xlat/access_flags.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000340
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000341static int
342decode_access(struct tcb *tcp, int offset)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000343{
344 if (entering(tcp)) {
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000345 printpath(tcp, tcp->u_arg[offset]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200346 tprints(", ");
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000347 printflags(access_flags, tcp->u_arg[offset + 1], "?_OK");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000348 }
349 return 0;
350}
351
352int
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000353sys_access(struct tcb *tcp)
354{
355 return decode_access(tcp, 0);
356}
357
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000358int
359sys_faccessat(struct tcb *tcp)
360{
361 if (entering(tcp))
Dmitry V. Levin31382132011-03-04 05:08:02 +0300362 print_dirfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000363 return decode_access(tcp, 1);
364}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000365
366int
Denys Vlasenko1d632462009-04-14 12:51:00 +0000367sys_umask(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000368{
369 if (entering(tcp)) {
370 tprintf("%#lo", tcp->u_arg[0]);
371 }
372 return RVAL_OCTAL;
373}
374
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000375#include "xlat/whence_codes.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000376
Denys Vlasenko386b8712013-02-17 01:38:14 +0100377/* Linux kernel has exactly one version of lseek:
378 * fs/read_write.c::SYSCALL_DEFINE3(lseek, unsigned, fd, off_t, offset, unsigned, origin)
379 * In kernel, off_t is always the same as (kernel's) long
380 * (see include/uapi/asm-generic/posix_types.h),
381 * which means that on x32 we need to use tcp->ext_arg[N] to get offset argument.
Denys Vlasenko09a87ae2013-02-17 13:17:49 +0100382 * Use test/x32_lseek.c to test lseek decoding.
Denys Vlasenko386b8712013-02-17 01:38:14 +0100383 */
H.J. Luc933f272012-04-16 17:41:13 +0200384#if defined(LINUX_MIPSN32) || defined(X32)
Roland McGrath542c2c62008-05-20 01:11:56 +0000385int
Denys Vlasenko1d632462009-04-14 12:51:00 +0000386sys_lseek(struct tcb *tcp)
Roland McGrath542c2c62008-05-20 01:11:56 +0000387{
388 long long offset;
Denys Vlasenko386b8712013-02-17 01:38:14 +0100389 int whence;
Roland McGrath542c2c62008-05-20 01:11:56 +0000390
391 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +0300392 printfd(tcp, tcp->u_arg[0]);
Roland McGrath542c2c62008-05-20 01:11:56 +0000393 offset = tcp->ext_arg[1];
Denys Vlasenko386b8712013-02-17 01:38:14 +0100394 whence = tcp->u_arg[2];
395 if (whence == SEEK_SET)
396 tprintf(", %llu, ", offset);
Roland McGrath542c2c62008-05-20 01:11:56 +0000397 else
Denys Vlasenko386b8712013-02-17 01:38:14 +0100398 tprintf(", %lld, ", offset);
Denys Vlasenko782d90f2013-02-17 12:47:44 +0100399 printxval(whence_codes, whence, "SEEK_???");
Roland McGrath542c2c62008-05-20 01:11:56 +0000400 }
H.J. Ludd0130b2012-04-16 12:16:45 +0200401 return RVAL_LUDECIMAL;
Roland McGrath542c2c62008-05-20 01:11:56 +0000402}
H.J. Ludd0130b2012-04-16 12:16:45 +0200403#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000404int
Denys Vlasenko1d632462009-04-14 12:51:00 +0000405sys_lseek(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000406{
Denys Vlasenko06121762013-02-17 20:08:50 +0100407 long offset;
Denys Vlasenko386b8712013-02-17 01:38:14 +0100408 int whence;
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000409
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000410 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +0300411 printfd(tcp, tcp->u_arg[0]);
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000412 offset = tcp->u_arg[1];
Denys Vlasenko386b8712013-02-17 01:38:14 +0100413 whence = tcp->u_arg[2];
414 if (whence == SEEK_SET)
415 tprintf(", %lu, ", offset);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000416 else
Denys Vlasenko386b8712013-02-17 01:38:14 +0100417 tprintf(", %ld, ", offset);
Denys Vlasenko782d90f2013-02-17 12:47:44 +0100418 printxval(whence_codes, whence, "SEEK_???");
Roland McGrath186c5ac2002-12-15 23:58:23 +0000419 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000420 return RVAL_UDECIMAL;
421}
John Hughes5a826b82001-03-07 13:21:24 +0000422#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000423
Denys Vlasenko386b8712013-02-17 01:38:14 +0100424/* llseek syscall takes explicitly two ulong arguments hi, lo,
425 * rather than one 64-bit argument for which LONG_LONG works
426 * appropriate for the native byte order.
427 *
428 * See kernel's fs/read_write.c::SYSCALL_DEFINE5(llseek, ...)
429 *
430 * hi,lo are "unsigned longs" and combined exactly this way in kernel:
431 * ((loff_t) hi << 32) | lo
Denys Vlasenko09a87ae2013-02-17 13:17:49 +0100432 * Note that for architectures with kernel's long wider than userspace long
Denys Vlasenko386b8712013-02-17 01:38:14 +0100433 * (such as x32), combining code will use *kernel's*, i.e. *wide* longs
Denys Vlasenko06121762013-02-17 20:08:50 +0100434 * for hi and lo. We would need to use tcp->ext_arg[N] on x32...
435 * ...however, x32 (and x86_64) does not _have_ llseek syscall as such.
Denys Vlasenko386b8712013-02-17 01:38:14 +0100436 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000437int
Denys Vlasenko1d632462009-04-14 12:51:00 +0000438sys_llseek(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000439{
Denys Vlasenko1d632462009-04-14 12:51:00 +0000440 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +0300441 printfd(tcp, tcp->u_arg[0]);
Denys Vlasenko1d632462009-04-14 12:51:00 +0000442 if (tcp->u_arg[4] == SEEK_SET)
Dmitry V. Levin31382132011-03-04 05:08:02 +0300443 tprintf(", %llu, ",
Denys Vlasenko386b8712013-02-17 01:38:14 +0100444 ((long long) tcp->u_arg[1]) << 32 |
Dmitry V. Levin31382132011-03-04 05:08:02 +0300445 (unsigned long long) (unsigned) tcp->u_arg[2]);
Denys Vlasenko1d632462009-04-14 12:51:00 +0000446 else
Dmitry V. Levin31382132011-03-04 05:08:02 +0300447 tprintf(", %lld, ",
Denys Vlasenko386b8712013-02-17 01:38:14 +0100448 ((long long) tcp->u_arg[1]) << 32 |
Dmitry V. Levin31382132011-03-04 05:08:02 +0300449 (unsigned long long) (unsigned) tcp->u_arg[2]);
Denys Vlasenko1d632462009-04-14 12:51:00 +0000450 }
451 else {
Denys Vlasenko386b8712013-02-17 01:38:14 +0100452 long long off;
Denys Vlasenko1d632462009-04-14 12:51:00 +0000453 if (syserror(tcp) || umove(tcp, tcp->u_arg[3], &off) < 0)
454 tprintf("%#lx, ", tcp->u_arg[3]);
455 else
456 tprintf("[%llu], ", off);
Denys Vlasenko782d90f2013-02-17 12:47:44 +0100457 printxval(whence_codes, tcp->u_arg[4], "SEEK_???");
Denys Vlasenko1d632462009-04-14 12:51:00 +0000458 }
459 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000460}
Roland McGrath186c5ac2002-12-15 23:58:23 +0000461
462int
Denys Vlasenko1d632462009-04-14 12:51:00 +0000463sys_readahead(struct tcb *tcp)
Roland McGrath186c5ac2002-12-15 23:58:23 +0000464{
Denys Vlasenko1d632462009-04-14 12:51:00 +0000465 if (entering(tcp)) {
Andreas Schwabb5600fc2009-11-04 17:08:34 +0100466 int argn;
Dmitry V. Levin31382132011-03-04 05:08:02 +0300467 printfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin3c49b022014-08-07 00:07:28 +0000468 argn = printllval(tcp, ", %lld", 1);
Andreas Schwabb5600fc2009-11-04 17:08:34 +0100469 tprintf(", %ld", tcp->u_arg[argn]);
Denys Vlasenko1d632462009-04-14 12:51:00 +0000470 }
471 return 0;
Roland McGrath186c5ac2002-12-15 23:58:23 +0000472}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000473
474int
Denys Vlasenko1d632462009-04-14 12:51:00 +0000475sys_truncate(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000476{
477 if (entering(tcp)) {
478 printpath(tcp, tcp->u_arg[0]);
479 tprintf(", %lu", tcp->u_arg[1]);
480 }
481 return 0;
482}
483
John Hughes96f51472001-03-06 16:50:41 +0000484int
Denys Vlasenko1d632462009-04-14 12:51:00 +0000485sys_truncate64(struct tcb *tcp)
John Hughes96f51472001-03-06 16:50:41 +0000486{
487 if (entering(tcp)) {
488 printpath(tcp, tcp->u_arg[0]);
Dmitry V. Levin3c49b022014-08-07 00:07:28 +0000489 printllval(tcp, ", %llu", 1);
John Hughes96f51472001-03-06 16:50:41 +0000490 }
491 return 0;
492}
John Hughes96f51472001-03-06 16:50:41 +0000493
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000494int
Denys Vlasenko1d632462009-04-14 12:51:00 +0000495sys_ftruncate(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000496{
497 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +0300498 printfd(tcp, tcp->u_arg[0]);
499 tprintf(", %lu", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000500 }
501 return 0;
502}
503
John Hughes96f51472001-03-06 16:50:41 +0000504int
Denys Vlasenko1d632462009-04-14 12:51:00 +0000505sys_ftruncate64(struct tcb *tcp)
John Hughes96f51472001-03-06 16:50:41 +0000506{
507 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +0300508 printfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin3c49b022014-08-07 00:07:28 +0000509 printllval(tcp, ", %llu", 1);
John Hughes96f51472001-03-06 16:50:41 +0000510 }
511 return 0;
512}
John Hughes96f51472001-03-06 16:50:41 +0000513
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000514/* several stats */
515
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000516#include "xlat/modetypes.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000517
Roland McGrathf9c49b22004-10-06 22:11:54 +0000518static const char *
Denys Vlasenko1d632462009-04-14 12:51:00 +0000519sprintmode(int mode)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000520{
Denys Vlasenko1945ccc2012-02-27 14:37:48 +0100521 static char buf[sizeof("S_IFSOCK|S_ISUID|S_ISGID|S_ISVTX|%o")
522 + sizeof(int)*3
523 + /*paranoia:*/ 8];
Roland McGrathf9c49b22004-10-06 22:11:54 +0000524 const char *s;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000525
526 if ((mode & S_IFMT) == 0)
527 s = "";
528 else if ((s = xlookup(modetypes, mode & S_IFMT)) == NULL) {
529 sprintf(buf, "%#o", mode);
530 return buf;
531 }
Denys Vlasenko1945ccc2012-02-27 14:37:48 +0100532 s = buf + sprintf(buf, "%s%s%s%s", s,
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000533 (mode & S_ISUID) ? "|S_ISUID" : "",
534 (mode & S_ISGID) ? "|S_ISGID" : "",
535 (mode & S_ISVTX) ? "|S_ISVTX" : "");
536 mode &= ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX);
537 if (mode)
Denys Vlasenko1945ccc2012-02-27 14:37:48 +0100538 sprintf((char*)s, "|%#o", mode);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000539 s = (*buf == '|') ? buf + 1 : buf;
540 return *s ? s : "0";
541}
542
543static char *
Dmitry V. Levindc7715b2008-04-19 23:45:09 +0000544sprinttime(time_t t)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000545{
546 struct tm *tmp;
Denys Vlasenko1945ccc2012-02-27 14:37:48 +0100547 static char buf[sizeof("yyyy/mm/dd-hh:mm:ss")];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000548
549 if (t == 0) {
Dmitry V. Levindc7715b2008-04-19 23:45:09 +0000550 strcpy(buf, "0");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000551 return buf;
552 }
Denys Vlasenko5d645812011-08-20 12:48:18 +0200553 tmp = localtime(&t);
554 if (tmp)
Dmitry V. Levindc7715b2008-04-19 23:45:09 +0000555 snprintf(buf, sizeof buf, "%02d/%02d/%02d-%02d:%02d:%02d",
556 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
557 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
558 else
559 snprintf(buf, sizeof buf, "%lu", (unsigned long) t);
560
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000561 return buf;
562}
563
Denys Vlasenko9472a272013-02-12 11:43:46 +0100564#if defined(SPARC) || defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000565typedef struct {
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000566 int tv_sec;
567 int tv_nsec;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000568} timestruct_t;
569
570struct solstat {
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000571 unsigned st_dev;
572 int st_pad1[3]; /* network id */
573 unsigned st_ino;
574 unsigned st_mode;
575 unsigned st_nlink;
576 unsigned st_uid;
577 unsigned st_gid;
578 unsigned st_rdev;
579 int st_pad2[2];
580 int st_size;
581 int st_pad3; /* st_size, off_t expansion */
582 timestruct_t st_atime;
583 timestruct_t st_mtime;
584 timestruct_t st_ctime;
585 int st_blksize;
586 int st_blocks;
587 char st_fstype[16];
588 int st_pad4[8]; /* expansion area */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000589};
590
591static void
Dmitry V. Levinb838b1e2008-04-19 23:47:47 +0000592printstatsol(struct tcb *tcp, long addr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000593{
594 struct solstat statbuf;
595
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000596 if (umove(tcp, addr, &statbuf) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200597 tprints("{...}");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000598 return;
599 }
600 if (!abbrev(tcp)) {
601 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
602 (unsigned long) ((statbuf.st_dev >> 18) & 0x3fff),
603 (unsigned long) (statbuf.st_dev & 0x3ffff),
604 (unsigned long) statbuf.st_ino,
605 sprintmode(statbuf.st_mode));
606 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
607 (unsigned long) statbuf.st_nlink,
608 (unsigned long) statbuf.st_uid,
609 (unsigned long) statbuf.st_gid);
610 tprintf("st_blksize=%lu, ", (unsigned long) statbuf.st_blksize);
611 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
612 }
613 else
614 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
615 switch (statbuf.st_mode & S_IFMT) {
616 case S_IFCHR: case S_IFBLK:
617 tprintf("st_rdev=makedev(%lu, %lu), ",
618 (unsigned long) ((statbuf.st_rdev >> 18) & 0x3fff),
619 (unsigned long) (statbuf.st_rdev & 0x3ffff));
620 break;
621 default:
622 tprintf("st_size=%u, ", statbuf.st_size);
623 break;
624 }
625 if (!abbrev(tcp)) {
Dmitry V. Levinb838b1e2008-04-19 23:47:47 +0000626 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime.tv_sec));
627 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime.tv_sec));
628 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime.tv_sec));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000629 }
630 else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200631 tprints("...}");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000632}
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000633
Denys Vlasenko9472a272013-02-12 11:43:46 +0100634# if defined(SPARC64)
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000635static void
Denys Vlasenko1d632462009-04-14 12:51:00 +0000636printstat_sparc64(struct tcb *tcp, long addr)
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000637{
638 struct stat_sparc64 statbuf;
639
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000640 if (umove(tcp, addr, &statbuf) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200641 tprints("{...}");
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000642 return;
643 }
644
645 if (!abbrev(tcp)) {
646 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
647 (unsigned long) major(statbuf.st_dev),
648 (unsigned long) minor(statbuf.st_dev),
649 (unsigned long) statbuf.st_ino,
650 sprintmode(statbuf.st_mode));
651 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
652 (unsigned long) statbuf.st_nlink,
653 (unsigned long) statbuf.st_uid,
654 (unsigned long) statbuf.st_gid);
655 tprintf("st_blksize=%lu, ",
656 (unsigned long) statbuf.st_blksize);
657 tprintf("st_blocks=%lu, ",
658 (unsigned long) statbuf.st_blocks);
659 }
660 else
661 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
662 switch (statbuf.st_mode & S_IFMT) {
663 case S_IFCHR: case S_IFBLK:
664 tprintf("st_rdev=makedev(%lu, %lu), ",
665 (unsigned long) major(statbuf.st_rdev),
666 (unsigned long) minor(statbuf.st_rdev));
667 break;
668 default:
669 tprintf("st_size=%lu, ", statbuf.st_size);
670 break;
671 }
672 if (!abbrev(tcp)) {
673 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
674 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
Denys Vlasenko1945ccc2012-02-27 14:37:48 +0100675 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000676 }
677 else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200678 tprints("...}");
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000679}
Denys Vlasenko9472a272013-02-12 11:43:46 +0100680# endif /* SPARC64 */
681#endif /* SPARC[64] */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000682
Denys Vlasenko84703742012-02-25 02:38:52 +0100683#if defined POWERPC64
Andreas Schwabd69fa492010-07-12 21:39:57 +0200684struct stat_powerpc32 {
685 unsigned int st_dev;
686 unsigned int st_ino;
687 unsigned int st_mode;
688 unsigned short st_nlink;
689 unsigned int st_uid;
690 unsigned int st_gid;
691 unsigned int st_rdev;
692 unsigned int st_size;
693 unsigned int st_blksize;
694 unsigned int st_blocks;
695 unsigned int st_atime;
696 unsigned int st_atime_nsec;
697 unsigned int st_mtime;
698 unsigned int st_mtime_nsec;
699 unsigned int st_ctime;
700 unsigned int st_ctime_nsec;
701 unsigned int __unused4;
702 unsigned int __unused5;
703};
704
705static void
706printstat_powerpc32(struct tcb *tcp, long addr)
707{
708 struct stat_powerpc32 statbuf;
709
710 if (umove(tcp, addr, &statbuf) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200711 tprints("{...}");
Andreas Schwabd69fa492010-07-12 21:39:57 +0200712 return;
713 }
714
715 if (!abbrev(tcp)) {
716 tprintf("{st_dev=makedev(%u, %u), st_ino=%u, st_mode=%s, ",
717 major(statbuf.st_dev), minor(statbuf.st_dev),
718 statbuf.st_ino,
719 sprintmode(statbuf.st_mode));
720 tprintf("st_nlink=%u, st_uid=%u, st_gid=%u, ",
721 statbuf.st_nlink, statbuf.st_uid, statbuf.st_gid);
722 tprintf("st_blksize=%u, ", statbuf.st_blksize);
723 tprintf("st_blocks=%u, ", statbuf.st_blocks);
724 }
725 else
726 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
727 switch (statbuf.st_mode & S_IFMT) {
728 case S_IFCHR: case S_IFBLK:
729 tprintf("st_rdev=makedev(%lu, %lu), ",
730 (unsigned long) major(statbuf.st_rdev),
731 (unsigned long) minor(statbuf.st_rdev));
732 break;
733 default:
734 tprintf("st_size=%u, ", statbuf.st_size);
735 break;
736 }
737 if (!abbrev(tcp)) {
738 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
739 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
Denys Vlasenko1945ccc2012-02-27 14:37:48 +0100740 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
Andreas Schwabd69fa492010-07-12 21:39:57 +0200741 }
742 else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200743 tprints("...}");
Andreas Schwabd69fa492010-07-12 21:39:57 +0200744}
Denys Vlasenko84703742012-02-25 02:38:52 +0100745#endif /* POWERPC64 */
Andreas Schwabd69fa492010-07-12 21:39:57 +0200746
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000747#include "xlat/fileflags.h"
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000748
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000749static void
Denys Vlasenko1d632462009-04-14 12:51:00 +0000750realprintstat(struct tcb *tcp, struct stat *statbuf)
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000751{
Denys Vlasenko1d632462009-04-14 12:51:00 +0000752 if (!abbrev(tcp)) {
753 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
754 (unsigned long) major(statbuf->st_dev),
755 (unsigned long) minor(statbuf->st_dev),
756 (unsigned long) statbuf->st_ino,
757 sprintmode(statbuf->st_mode));
758 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
759 (unsigned long) statbuf->st_nlink,
760 (unsigned long) statbuf->st_uid,
761 (unsigned long) statbuf->st_gid);
Roland McGrath6d2b3492002-12-30 00:51:30 +0000762#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Denys Vlasenko1d632462009-04-14 12:51:00 +0000763 tprintf("st_blksize=%lu, ", (unsigned long) statbuf->st_blksize);
764#endif
Roland McGrath6d2b3492002-12-30 00:51:30 +0000765#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Denys Vlasenko1d632462009-04-14 12:51:00 +0000766 tprintf("st_blocks=%lu, ", (unsigned long) statbuf->st_blocks);
767#endif
768 }
769 else
770 tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode));
771 switch (statbuf->st_mode & S_IFMT) {
772 case S_IFCHR: case S_IFBLK:
Roland McGrath6d2b3492002-12-30 00:51:30 +0000773#ifdef HAVE_STRUCT_STAT_ST_RDEV
Denys Vlasenko1d632462009-04-14 12:51:00 +0000774 tprintf("st_rdev=makedev(%lu, %lu), ",
775 (unsigned long) major(statbuf->st_rdev),
776 (unsigned long) minor(statbuf->st_rdev));
Roland McGrath6d2b3492002-12-30 00:51:30 +0000777#else /* !HAVE_STRUCT_STAT_ST_RDEV */
Denys Vlasenko1d632462009-04-14 12:51:00 +0000778 tprintf("st_size=makedev(%lu, %lu), ",
779 (unsigned long) major(statbuf->st_size),
780 (unsigned long) minor(statbuf->st_size));
Roland McGrath6d2b3492002-12-30 00:51:30 +0000781#endif /* !HAVE_STRUCT_STAT_ST_RDEV */
Denys Vlasenko1d632462009-04-14 12:51:00 +0000782 break;
783 default:
Dmitry V. Levine9a06b72011-02-23 16:16:50 +0000784 tprintf("st_size=%lu, ", (unsigned long) statbuf->st_size);
Denys Vlasenko1d632462009-04-14 12:51:00 +0000785 break;
786 }
787 if (!abbrev(tcp)) {
788 tprintf("st_atime=%s, ", sprinttime(statbuf->st_atime));
789 tprintf("st_mtime=%s, ", sprinttime(statbuf->st_mtime));
790 tprintf("st_ctime=%s", sprinttime(statbuf->st_ctime));
Roland McGrath6d2b3492002-12-30 00:51:30 +0000791#if HAVE_STRUCT_STAT_ST_FLAGS
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200792 tprints(", st_flags=");
Roland McGrathb2dee132005-06-01 19:02:36 +0000793 printflags(fileflags, statbuf->st_flags, "UF_???");
John Hughesc0fc3fd2001-03-08 16:10:40 +0000794#endif
Roland McGrath6d2b3492002-12-30 00:51:30 +0000795#if HAVE_STRUCT_STAT_ST_ACLCNT
John Hughesc0fc3fd2001-03-08 16:10:40 +0000796 tprintf(", st_aclcnt=%d", statbuf->st_aclcnt);
797#endif
Roland McGrath6d2b3492002-12-30 00:51:30 +0000798#if HAVE_STRUCT_STAT_ST_LEVEL
John Hughesc0fc3fd2001-03-08 16:10:40 +0000799 tprintf(", st_level=%ld", statbuf->st_level);
800#endif
Roland McGrath6d2b3492002-12-30 00:51:30 +0000801#if HAVE_STRUCT_STAT_ST_FSTYPE
John Hughesc0fc3fd2001-03-08 16:10:40 +0000802 tprintf(", st_fstype=%.*s",
803 (int) sizeof statbuf->st_fstype, statbuf->st_fstype);
804#endif
Roland McGrath6d2b3492002-12-30 00:51:30 +0000805#if HAVE_STRUCT_STAT_ST_GEN
John Hughesc0fc3fd2001-03-08 16:10:40 +0000806 tprintf(", st_gen=%u", statbuf->st_gen);
807#endif
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200808 tprints("}");
Denys Vlasenko1d632462009-04-14 12:51:00 +0000809 }
810 else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200811 tprints("...}");
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000812}
813
Dmitry V. Levin0eeda2c2013-05-01 16:37:08 +0000814#ifndef X32
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000815static void
Denys Vlasenko1d632462009-04-14 12:51:00 +0000816printstat(struct tcb *tcp, long addr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000817{
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000818 struct stat statbuf;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000819
Denys Vlasenko4e718b52009-04-20 18:30:13 +0000820 if (!addr) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200821 tprints("NULL");
Denys Vlasenko4e718b52009-04-20 18:30:13 +0000822 return;
823 }
824 if (syserror(tcp) || !verbose(tcp)) {
825 tprintf("%#lx", addr);
826 return;
827 }
828
Denys Vlasenko9472a272013-02-12 11:43:46 +0100829#if defined(SPARC) || defined(SPARC64)
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +0000830 if (current_personality == 1) {
831 printstatsol(tcp, addr);
832 return;
833 }
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000834#ifdef SPARC64
835 else if (current_personality == 2) {
836 printstat_sparc64(tcp, addr);
837 return;
838 }
839#endif
Denys Vlasenko9472a272013-02-12 11:43:46 +0100840#endif /* SPARC[64] */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000841
Denys Vlasenko84703742012-02-25 02:38:52 +0100842#if defined POWERPC64
Andreas Schwabd69fa492010-07-12 21:39:57 +0200843 if (current_personality == 1) {
844 printstat_powerpc32(tcp, addr);
845 return;
846 }
847#endif
848
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000849 if (umove(tcp, addr, &statbuf) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200850 tprints("{...}");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000851 return;
852 }
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000853
854 realprintstat(tcp, &statbuf);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000855}
Dmitry V. Levin0eeda2c2013-05-01 16:37:08 +0000856#else /* X32 */
857# define printstat printstat64
858#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000859
Elliott Hughes391c0d82014-04-03 17:50:14 -0700860#if !defined HAVE_STAT64 && (defined AARCH64 || defined X86_64)
Roland McGrathe6d0f712007-08-07 01:22:49 +0000861/*
862 * Linux x86_64 has unified `struct stat' but its i386 biarch needs
863 * `struct stat64'. Its <asm-i386/stat.h> definition expects 32-bit `long'.
864 * <linux/include/asm-x86_64/ia32.h> is not in the public includes set.
865 * __GNUC__ is needed for the required __attribute__ below.
Elliott Hughes391c0d82014-04-03 17:50:14 -0700866 *
867 * Similarly, aarch64 has a unified `struct stat' but its arm personality
868 * needs `struct stat64' (which also expects a 32-bit `long' but which
869 * shouldn't be packed).
Roland McGrathe6d0f712007-08-07 01:22:49 +0000870 */
871struct stat64 {
872 unsigned long long st_dev;
873 unsigned char __pad0[4];
874 unsigned int __st_ino;
875 unsigned int st_mode;
876 unsigned int st_nlink;
877 unsigned int st_uid;
878 unsigned int st_gid;
879 unsigned long long st_rdev;
880 unsigned char __pad3[4];
881 long long st_size;
882 unsigned int st_blksize;
883 unsigned long long st_blocks;
884 unsigned int st_atime;
885 unsigned int st_atime_nsec;
886 unsigned int st_mtime;
887 unsigned int st_mtime_nsec;
888 unsigned int st_ctime;
889 unsigned int st_ctime_nsec;
890 unsigned long long st_ino;
Elliott Hughes391c0d82014-04-03 17:50:14 -0700891}
892# if defined X86_64
893 __attribute__((packed))
894# define STAT64_SIZE 96
895#else
896# define STAT64_SIZE 104
897# endif
898;
Roland McGrathe6d0f712007-08-07 01:22:49 +0000899# define HAVE_STAT64 1
Roland McGrathe6d0f712007-08-07 01:22:49 +0000900#endif
901
Wichert Akkermanc7926982000-04-10 22:22:31 +0000902#ifdef HAVE_STAT64
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000903static void
Denys Vlasenko1d632462009-04-14 12:51:00 +0000904printstat64(struct tcb *tcp, long addr)
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000905{
Dmitry V. Levin0eeda2c2013-05-01 16:37:08 +0000906#ifdef X32
907 struct stat statbuf;
908#else
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000909 struct stat64 statbuf;
Dmitry V. Levin0eeda2c2013-05-01 16:37:08 +0000910#endif
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000911
Denys Vlasenko4e718b52009-04-20 18:30:13 +0000912#ifdef STAT64_SIZE
Roland McGrathe6d0f712007-08-07 01:22:49 +0000913 (void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
914#endif
915
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000916 if (!addr) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200917 tprints("NULL");
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000918 return;
919 }
920 if (syserror(tcp) || !verbose(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000921 tprintf("%#lx", addr);
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000922 return;
923 }
Denys Vlasenko4e718b52009-04-20 18:30:13 +0000924
Denys Vlasenko9472a272013-02-12 11:43:46 +0100925#if defined(SPARC) || defined(SPARC64)
Denys Vlasenko4e718b52009-04-20 18:30:13 +0000926 if (current_personality == 1) {
927 printstatsol(tcp, addr);
928 return;
929 }
930# ifdef SPARC64
931 else if (current_personality == 2) {
932 printstat_sparc64(tcp, addr);
933 return;
934 }
935# endif
Denys Vlasenko9472a272013-02-12 11:43:46 +0100936#endif /* SPARC[64] */
Denys Vlasenko4e718b52009-04-20 18:30:13 +0000937
Elliott Hughes391c0d82014-04-03 17:50:14 -0700938#if defined AARCH64
939 if (current_personality != 0) {
940 printstat(tcp, addr);
941 return;
942 }
943#endif
Denys Vlasenko84703742012-02-25 02:38:52 +0100944#if defined X86_64
H.J. Lu35be5812012-04-16 13:00:01 +0200945 if (current_personality != 1) {
Andreas Schwab61b74352009-10-16 11:37:13 +0200946 printstat(tcp, addr);
947 return;
948 }
949#endif
Dmitry V. Levinff896f72009-10-21 13:43:57 +0000950
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000951 if (umove(tcp, addr, &statbuf) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200952 tprints("{...}");
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000953 return;
954 }
955
956 if (!abbrev(tcp)) {
Wichert Akkermand077c452000-08-10 18:16:15 +0000957 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000958 (unsigned long) major(statbuf.st_dev),
959 (unsigned long) minor(statbuf.st_dev),
Wichert Akkermand077c452000-08-10 18:16:15 +0000960 (unsigned long long) statbuf.st_ino,
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000961 sprintmode(statbuf.st_mode));
962 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
963 (unsigned long) statbuf.st_nlink,
964 (unsigned long) statbuf.st_uid,
965 (unsigned long) statbuf.st_gid);
Roland McGrath6d2b3492002-12-30 00:51:30 +0000966#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000967 tprintf("st_blksize=%lu, ",
968 (unsigned long) statbuf.st_blksize);
Roland McGrath6d2b3492002-12-30 00:51:30 +0000969#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
970#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000971 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
Roland McGrath6d2b3492002-12-30 00:51:30 +0000972#endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000973 }
974 else
975 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
976 switch (statbuf.st_mode & S_IFMT) {
977 case S_IFCHR: case S_IFBLK:
Roland McGrath6d2b3492002-12-30 00:51:30 +0000978#ifdef HAVE_STRUCT_STAT_ST_RDEV
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000979 tprintf("st_rdev=makedev(%lu, %lu), ",
980 (unsigned long) major(statbuf.st_rdev),
981 (unsigned long) minor(statbuf.st_rdev));
Roland McGrath6d2b3492002-12-30 00:51:30 +0000982#else /* !HAVE_STRUCT_STAT_ST_RDEV */
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000983 tprintf("st_size=makedev(%lu, %lu), ",
984 (unsigned long) major(statbuf.st_size),
985 (unsigned long) minor(statbuf.st_size));
Roland McGrath6d2b3492002-12-30 00:51:30 +0000986#endif /* !HAVE_STRUCT_STAT_ST_RDEV */
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000987 break;
988 default:
Roland McGrathc7bd4d32007-08-07 01:05:19 +0000989 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000990 break;
991 }
992 if (!abbrev(tcp)) {
993 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
994 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
John Hughesc0fc3fd2001-03-08 16:10:40 +0000995 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
Roland McGrath6d2b3492002-12-30 00:51:30 +0000996#if HAVE_STRUCT_STAT_ST_FLAGS
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200997 tprints(", st_flags=");
Roland McGrathb2dee132005-06-01 19:02:36 +0000998 printflags(fileflags, statbuf.st_flags, "UF_???");
John Hughesc0fc3fd2001-03-08 16:10:40 +0000999#endif
Roland McGrath6d2b3492002-12-30 00:51:30 +00001000#if HAVE_STRUCT_STAT_ST_ACLCNT
John Hughesc0fc3fd2001-03-08 16:10:40 +00001001 tprintf(", st_aclcnt=%d", statbuf.st_aclcnt);
1002#endif
Roland McGrath6d2b3492002-12-30 00:51:30 +00001003#if HAVE_STRUCT_STAT_ST_LEVEL
John Hughesc0fc3fd2001-03-08 16:10:40 +00001004 tprintf(", st_level=%ld", statbuf.st_level);
1005#endif
Roland McGrath6d2b3492002-12-30 00:51:30 +00001006#if HAVE_STRUCT_STAT_ST_FSTYPE
John Hughesc0fc3fd2001-03-08 16:10:40 +00001007 tprintf(", st_fstype=%.*s",
1008 (int) sizeof statbuf.st_fstype, statbuf.st_fstype);
1009#endif
Roland McGrath6d2b3492002-12-30 00:51:30 +00001010#if HAVE_STRUCT_STAT_ST_GEN
John Hughesc0fc3fd2001-03-08 16:10:40 +00001011 tprintf(", st_gen=%u", statbuf.st_gen);
1012#endif
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001013 tprints("}");
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001014 }
1015 else
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001016 tprints("...}");
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001017}
Wichert Akkermanc7926982000-04-10 22:22:31 +00001018#endif /* HAVE_STAT64 */
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001019
Denys Vlasenko8435d672013-02-18 15:47:57 +01001020#if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001021static void
Denys Vlasenko1d632462009-04-14 12:51:00 +00001022convertoldstat(const struct __old_kernel_stat *oldbuf, struct stat *newbuf)
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001023{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001024 newbuf->st_dev = oldbuf->st_dev;
1025 newbuf->st_ino = oldbuf->st_ino;
1026 newbuf->st_mode = oldbuf->st_mode;
1027 newbuf->st_nlink = oldbuf->st_nlink;
1028 newbuf->st_uid = oldbuf->st_uid;
1029 newbuf->st_gid = oldbuf->st_gid;
1030 newbuf->st_rdev = oldbuf->st_rdev;
1031 newbuf->st_size = oldbuf->st_size;
1032 newbuf->st_atime = oldbuf->st_atime;
1033 newbuf->st_mtime = oldbuf->st_mtime;
1034 newbuf->st_ctime = oldbuf->st_ctime;
1035 newbuf->st_blksize = 0; /* not supported in old_stat */
1036 newbuf->st_blocks = 0; /* not supported in old_stat */
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001037}
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001038
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001039static void
Denys Vlasenko1d632462009-04-14 12:51:00 +00001040printoldstat(struct tcb *tcp, long addr)
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001041{
Wichert Akkerman25d0c4f1999-04-18 19:35:42 +00001042 struct __old_kernel_stat statbuf;
1043 struct stat newstatbuf;
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001044
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001045 if (!addr) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001046 tprints("NULL");
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001047 return;
1048 }
1049 if (syserror(tcp) || !verbose(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001050 tprintf("%#lx", addr);
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001051 return;
1052 }
Denys Vlasenko4e718b52009-04-20 18:30:13 +00001053
Denys Vlasenko9472a272013-02-12 11:43:46 +01001054# if defined(SPARC) || defined(SPARC64)
Denys Vlasenko4e718b52009-04-20 18:30:13 +00001055 if (current_personality == 1) {
1056 printstatsol(tcp, addr);
1057 return;
1058 }
Denys Vlasenko84703742012-02-25 02:38:52 +01001059# endif
Denys Vlasenko4e718b52009-04-20 18:30:13 +00001060
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001061 if (umove(tcp, addr, &statbuf) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001062 tprints("{...}");
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001063 return;
1064 }
1065
1066 convertoldstat(&statbuf, &newstatbuf);
1067 realprintstat(tcp, &newstatbuf);
1068}
Denys Vlasenko84703742012-02-25 02:38:52 +01001069#endif
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001070
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001071int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001072sys_stat(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001073{
1074 if (entering(tcp)) {
1075 printpath(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001076 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001077 } else {
1078 printstat(tcp, tcp->u_arg[1]);
1079 }
1080 return 0;
1081}
1082
Dmitry V. Levin0eeda2c2013-05-01 16:37:08 +00001083#ifdef X32
1084static void
1085printstat64_x32(struct tcb *tcp, long addr)
1086{
1087 struct stat64 statbuf;
1088
1089 if (!addr) {
1090 tprints("NULL");
1091 return;
1092 }
1093 if (syserror(tcp) || !verbose(tcp)) {
1094 tprintf("%#lx", addr);
1095 return;
1096 }
1097
1098 if (umove(tcp, addr, &statbuf) < 0) {
1099 tprints("{...}");
1100 return;
1101 }
1102
1103 if (!abbrev(tcp)) {
1104 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
1105 (unsigned long) major(statbuf.st_dev),
1106 (unsigned long) minor(statbuf.st_dev),
1107 (unsigned long long) statbuf.st_ino,
1108 sprintmode(statbuf.st_mode));
1109 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
1110 (unsigned long) statbuf.st_nlink,
1111 (unsigned long) statbuf.st_uid,
1112 (unsigned long) statbuf.st_gid);
1113 tprintf("st_blksize=%lu, ",
1114 (unsigned long) statbuf.st_blksize);
1115 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
1116 }
1117 else
1118 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
1119 switch (statbuf.st_mode & S_IFMT) {
1120 case S_IFCHR: case S_IFBLK:
1121 tprintf("st_rdev=makedev(%lu, %lu), ",
1122 (unsigned long) major(statbuf.st_rdev),
1123 (unsigned long) minor(statbuf.st_rdev));
1124 break;
1125 default:
1126 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
1127 break;
1128 }
1129 if (!abbrev(tcp)) {
1130 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
1131 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
1132 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
1133 tprints("}");
1134 }
1135 else
1136 tprints("...}");
1137}
1138#endif /* X32 */
1139
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001140int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001141sys_stat64(struct tcb *tcp)
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001142{
1143#ifdef HAVE_STAT64
1144 if (entering(tcp)) {
1145 printpath(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001146 tprints(", ");
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001147 } else {
Dmitry V. Levin0eeda2c2013-05-01 16:37:08 +00001148# ifdef X32
1149 printstat64_x32(tcp, tcp->u_arg[1]);
1150# else
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001151 printstat64(tcp, tcp->u_arg[1]);
Dmitry V. Levin0eeda2c2013-05-01 16:37:08 +00001152# endif
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001153 }
1154 return 0;
1155#else
1156 return printargs(tcp);
1157#endif
1158}
1159
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001160#ifndef AT_SYMLINK_NOFOLLOW
Dmitry V. Levin7989ad42012-03-13 23:26:01 +00001161# define AT_SYMLINK_NOFOLLOW 0x100
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001162#endif
Dmitry V. Levin7989ad42012-03-13 23:26:01 +00001163#ifndef AT_REMOVEDIR
1164# define AT_REMOVEDIR 0x200
1165#endif
1166#ifndef AT_SYMLINK_FOLLOW
1167# define AT_SYMLINK_FOLLOW 0x400
1168#endif
1169#ifndef AT_NO_AUTOMOUNT
1170# define AT_NO_AUTOMOUNT 0x800
1171#endif
1172#ifndef AT_EMPTY_PATH
1173# define AT_EMPTY_PATH 0x1000
1174#endif
1175
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +00001176#include "xlat/at_flags.h"
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001177
1178int
1179sys_newfstatat(struct tcb *tcp)
1180{
1181 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +03001182 print_dirfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001183 printpath(tcp, tcp->u_arg[1]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001184 tprints(", ");
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001185 } else {
Andreas Schwabd69fa492010-07-12 21:39:57 +02001186#ifdef POWERPC64
1187 if (current_personality == 0)
1188 printstat(tcp, tcp->u_arg[2]);
1189 else
1190 printstat64(tcp, tcp->u_arg[2]);
1191#elif defined HAVE_STAT64
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001192 printstat64(tcp, tcp->u_arg[2]);
1193#else
1194 printstat(tcp, tcp->u_arg[2]);
1195#endif
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001196 tprints(", ");
Dmitry V. Levin7989ad42012-03-13 23:26:01 +00001197 printflags(at_flags, tcp->u_arg[3], "AT_???");
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001198 }
1199 return 0;
1200}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001201
Denys Vlasenko8435d672013-02-18 15:47:57 +01001202#if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001203int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001204sys_oldstat(struct tcb *tcp)
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001205{
1206 if (entering(tcp)) {
1207 printpath(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001208 tprints(", ");
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001209 } else {
1210 printoldstat(tcp, tcp->u_arg[1]);
1211 }
1212 return 0;
1213}
Denys Vlasenko84703742012-02-25 02:38:52 +01001214#endif
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001215
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001216int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001217sys_fstat(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001218{
Dmitry V. Levin31382132011-03-04 05:08:02 +03001219 if (entering(tcp)) {
1220 printfd(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001221 tprints(", ");
Dmitry V. Levin31382132011-03-04 05:08:02 +03001222 } else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001223 printstat(tcp, tcp->u_arg[1]);
1224 }
1225 return 0;
1226}
1227
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001228int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001229sys_fstat64(struct tcb *tcp)
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001230{
1231#ifdef HAVE_STAT64
Dmitry V. Levin31382132011-03-04 05:08:02 +03001232 if (entering(tcp)) {
1233 printfd(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001234 tprints(", ");
Dmitry V. Levin31382132011-03-04 05:08:02 +03001235 } else {
Dmitry V. Levin0eeda2c2013-05-01 16:37:08 +00001236# ifdef X32
1237 printstat64_x32(tcp, tcp->u_arg[1]);
1238# else
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001239 printstat64(tcp, tcp->u_arg[1]);
Dmitry V. Levin0eeda2c2013-05-01 16:37:08 +00001240# endif
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001241 }
1242 return 0;
1243#else
1244 return printargs(tcp);
1245#endif
1246}
1247
Denys Vlasenko8435d672013-02-18 15:47:57 +01001248#if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +00001249int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001250sys_oldfstat(struct tcb *tcp)
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001251{
Dmitry V. Levin31382132011-03-04 05:08:02 +03001252 if (entering(tcp)) {
1253 printfd(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001254 tprints(", ");
Dmitry V. Levin31382132011-03-04 05:08:02 +03001255 } else {
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001256 printoldstat(tcp, tcp->u_arg[1]);
1257 }
1258 return 0;
1259}
Denys Vlasenko84703742012-02-25 02:38:52 +01001260#endif
Wichert Akkerman328c5e71999-04-16 00:21:26 +00001261
Denys Vlasenko9472a272013-02-12 11:43:46 +01001262#if defined(SPARC) || defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001263
1264int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001265sys_xstat(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001266{
1267 if (entering(tcp)) {
1268 tprintf("%ld, ", tcp->u_arg[0]);
1269 printpath(tcp, tcp->u_arg[1]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001270 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001271 } else {
Denys Vlasenko84703742012-02-25 02:38:52 +01001272# ifdef _STAT64_VER
John Hughes8fe2c982001-03-06 09:45:18 +00001273 if (tcp->u_arg[0] == _STAT64_VER)
Denys Vlasenkob237b1b2012-02-27 13:56:59 +01001274 printstat64(tcp, tcp->u_arg[2]);
John Hughes8fe2c982001-03-06 09:45:18 +00001275 else
Denys Vlasenko84703742012-02-25 02:38:52 +01001276# endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001277 printstat(tcp, tcp->u_arg[2]);
1278 }
1279 return 0;
1280}
1281
1282int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001283sys_fxstat(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001284{
1285 if (entering(tcp))
1286 tprintf("%ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1]);
1287 else {
Denys Vlasenko84703742012-02-25 02:38:52 +01001288# ifdef _STAT64_VER
John Hughes8fe2c982001-03-06 09:45:18 +00001289 if (tcp->u_arg[0] == _STAT64_VER)
Denys Vlasenkob237b1b2012-02-27 13:56:59 +01001290 printstat64(tcp, tcp->u_arg[2]);
John Hughes8fe2c982001-03-06 09:45:18 +00001291 else
Denys Vlasenko84703742012-02-25 02:38:52 +01001292# endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001293 printstat(tcp, tcp->u_arg[2]);
1294 }
1295 return 0;
1296}
1297
1298int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001299sys_lxstat(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001300{
1301 if (entering(tcp)) {
1302 tprintf("%ld, ", tcp->u_arg[0]);
1303 printpath(tcp, tcp->u_arg[1]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001304 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001305 } else {
Denys Vlasenko84703742012-02-25 02:38:52 +01001306# ifdef _STAT64_VER
John Hughes8fe2c982001-03-06 09:45:18 +00001307 if (tcp->u_arg[0] == _STAT64_VER)
Denys Vlasenkob237b1b2012-02-27 13:56:59 +01001308 printstat64(tcp, tcp->u_arg[2]);
John Hughes8fe2c982001-03-06 09:45:18 +00001309 else
Denys Vlasenko84703742012-02-25 02:38:52 +01001310# endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001311 printstat(tcp, tcp->u_arg[2]);
1312 }
1313 return 0;
1314}
1315
1316int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001317sys_xmknod(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001318{
1319 int mode = tcp->u_arg[2];
1320
1321 if (entering(tcp)) {
1322 tprintf("%ld, ", tcp->u_arg[0]);
1323 printpath(tcp, tcp->u_arg[1]);
1324 tprintf(", %s", sprintmode(mode));
1325 switch (mode & S_IFMT) {
1326 case S_IFCHR: case S_IFBLK:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001327 tprintf(", makedev(%lu, %lu)",
1328 (unsigned long) ((tcp->u_arg[3] >> 18) & 0x3fff),
1329 (unsigned long) (tcp->u_arg[3] & 0x3ffff));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001330 break;
1331 default:
1332 break;
1333 }
1334 }
1335 return 0;
1336}
1337
Denys Vlasenko9472a272013-02-12 11:43:46 +01001338#endif /* SPARC[64] */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001339
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001340/* directory */
1341int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001342sys_chdir(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001343{
1344 if (entering(tcp)) {
1345 printpath(tcp, tcp->u_arg[0]);
1346 }
1347 return 0;
1348}
1349
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001350int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001351sys_link(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001352{
1353 if (entering(tcp)) {
1354 printpath(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001355 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001356 printpath(tcp, tcp->u_arg[1]);
1357 }
1358 return 0;
1359}
1360
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001361int
1362sys_linkat(struct tcb *tcp)
1363{
1364 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +03001365 print_dirfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001366 printpath(tcp, tcp->u_arg[1]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001367 tprints(", ");
Dmitry V. Levin31382132011-03-04 05:08:02 +03001368 print_dirfd(tcp, tcp->u_arg[2]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001369 printpath(tcp, tcp->u_arg[3]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001370 tprints(", ");
Dmitry V. Levin7989ad42012-03-13 23:26:01 +00001371 printflags(at_flags, tcp->u_arg[4], "AT_???");
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001372 }
1373 return 0;
1374}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001375
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001376int
1377sys_unlinkat(struct tcb *tcp)
1378{
1379 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +03001380 print_dirfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001381 printpath(tcp, tcp->u_arg[1]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001382 tprints(", ");
Dmitry V. Levin7989ad42012-03-13 23:26:01 +00001383 printflags(at_flags, tcp->u_arg[2], "AT_???");
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001384 }
1385 return 0;
1386}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001387
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001388int
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001389sys_symlinkat(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001390{
1391 if (entering(tcp)) {
1392 printpath(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001393 tprints(", ");
Dmitry V. Levin31382132011-03-04 05:08:02 +03001394 print_dirfd(tcp, tcp->u_arg[1]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001395 printpath(tcp, tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001396 }
1397 return 0;
1398}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001399
1400static int
1401decode_readlink(struct tcb *tcp, int offset)
1402{
1403 if (entering(tcp)) {
1404 printpath(tcp, tcp->u_arg[offset]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001405 tprints(", ");
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001406 } else {
1407 if (syserror(tcp))
1408 tprintf("%#lx", tcp->u_arg[offset + 1]);
1409 else
Denys Vlasenko3449ae82012-01-27 17:24:26 +01001410 /* Used to use printpathn(), but readlink
1411 * neither includes NUL in the returned count,
1412 * nor actually writes it into memory.
1413 * printpathn() would decide on printing
1414 * "..." continuation based on garbage
1415 * past return buffer's end.
1416 */
1417 printstr(tcp, tcp->u_arg[offset + 1], tcp->u_rval);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001418 tprintf(", %lu", tcp->u_arg[offset + 2]);
1419 }
1420 return 0;
1421}
1422
1423int
1424sys_readlink(struct tcb *tcp)
1425{
1426 return decode_readlink(tcp, 0);
1427}
1428
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001429int
1430sys_readlinkat(struct tcb *tcp)
1431{
1432 if (entering(tcp))
Dmitry V. Levin31382132011-03-04 05:08:02 +03001433 print_dirfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001434 return decode_readlink(tcp, 1);
1435}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001436
Mike Frysinger5b677ab2014-08-14 04:05:41 -04001437static void
1438decode_renameat(struct tcb *tcp)
1439{
1440 print_dirfd(tcp, tcp->u_arg[0]);
1441 printpath(tcp, tcp->u_arg[1]);
1442 tprints(", ");
1443 print_dirfd(tcp, tcp->u_arg[2]);
1444 printpath(tcp, tcp->u_arg[3]);
1445}
1446
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001447int
1448sys_renameat(struct tcb *tcp)
1449{
1450 if (entering(tcp)) {
Mike Frysinger5b677ab2014-08-14 04:05:41 -04001451 decode_renameat(tcp);
1452 }
1453 return 0;
1454}
1455
1456#include "xlat/rename_flags.h"
1457
1458int
1459sys_renameat2(struct tcb *tcp)
1460{
1461 if (entering(tcp)) {
1462 decode_renameat(tcp);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001463 tprints(", ");
Mike Frysinger5b677ab2014-08-14 04:05:41 -04001464 printflags(rename_flags, tcp->u_arg[4], "RENAME_??");
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001465 }
1466 return 0;
1467}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001468
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001469int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001470sys_chown(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001471{
1472 if (entering(tcp)) {
1473 printpath(tcp, tcp->u_arg[0]);
Roland McGrath6bc12202003-11-13 22:32:27 +00001474 printuid(", ", tcp->u_arg[1]);
1475 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001476 }
1477 return 0;
1478}
1479
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001480int
1481sys_fchownat(struct tcb *tcp)
1482{
1483 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +03001484 print_dirfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001485 printpath(tcp, tcp->u_arg[1]);
1486 printuid(", ", tcp->u_arg[2]);
1487 printuid(", ", tcp->u_arg[3]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001488 tprints(", ");
Dmitry V. Levin7989ad42012-03-13 23:26:01 +00001489 printflags(at_flags, tcp->u_arg[4], "AT_???");
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001490 }
1491 return 0;
1492}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001493
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001494int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001495sys_fchown(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001496{
1497 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +03001498 printfd(tcp, tcp->u_arg[0]);
Roland McGrath6bc12202003-11-13 22:32:27 +00001499 printuid(", ", tcp->u_arg[1]);
1500 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001501 }
1502 return 0;
1503}
1504
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001505static int
1506decode_chmod(struct tcb *tcp, int offset)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001507{
1508 if (entering(tcp)) {
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001509 printpath(tcp, tcp->u_arg[offset]);
1510 tprintf(", %#lo", tcp->u_arg[offset + 1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001511 }
1512 return 0;
1513}
1514
1515int
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001516sys_chmod(struct tcb *tcp)
1517{
1518 return decode_chmod(tcp, 0);
1519}
1520
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001521int
1522sys_fchmodat(struct tcb *tcp)
1523{
1524 if (entering(tcp))
Dmitry V. Levin31382132011-03-04 05:08:02 +03001525 print_dirfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001526 return decode_chmod(tcp, 1);
1527}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001528
1529int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001530sys_fchmod(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001531{
1532 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +03001533 printfd(tcp, tcp->u_arg[0]);
1534 tprintf(", %#lo", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001535 }
1536 return 0;
1537}
1538
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001539#ifdef ALPHA
1540int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001541sys_osf_utimes(struct tcb *tcp)
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001542{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001543 if (entering(tcp)) {
1544 printpath(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001545 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +00001546 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32, 0);
1547 }
1548 return 0;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001549}
1550#endif
1551
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001552static int
Roland McGrath6afc5652007-07-24 01:57:11 +00001553decode_utimes(struct tcb *tcp, int offset, int special)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001554{
1555 if (entering(tcp)) {
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001556 printpath(tcp, tcp->u_arg[offset]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001557 tprints(", ");
Roland McGrath6afc5652007-07-24 01:57:11 +00001558 if (tcp->u_arg[offset + 1] == 0)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001559 tprints("NULL");
Roland McGrath6afc5652007-07-24 01:57:11 +00001560 else {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001561 tprints("{");
Roland McGrath6afc5652007-07-24 01:57:11 +00001562 printtv_bitness(tcp, tcp->u_arg[offset + 1],
1563 BITNESS_CURRENT, special);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001564 tprints(", ");
Roland McGrathe6d0f712007-08-07 01:22:49 +00001565 printtv_bitness(tcp, tcp->u_arg[offset + 1]
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001566 + sizeof(struct timeval),
Roland McGrath6afc5652007-07-24 01:57:11 +00001567 BITNESS_CURRENT, special);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001568 tprints("}");
Roland McGrath6afc5652007-07-24 01:57:11 +00001569 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001570 }
1571 return 0;
1572}
1573
1574int
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001575sys_utimes(struct tcb *tcp)
1576{
Roland McGrath6afc5652007-07-24 01:57:11 +00001577 return decode_utimes(tcp, 0, 0);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001578}
1579
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001580int
1581sys_futimesat(struct tcb *tcp)
1582{
1583 if (entering(tcp))
Dmitry V. Levin31382132011-03-04 05:08:02 +03001584 print_dirfd(tcp, tcp->u_arg[0]);
Roland McGrath6afc5652007-07-24 01:57:11 +00001585 return decode_utimes(tcp, 1, 0);
1586}
1587
1588int
1589sys_utimensat(struct tcb *tcp)
1590{
1591 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +03001592 print_dirfd(tcp, tcp->u_arg[0]);
Roland McGrath6afc5652007-07-24 01:57:11 +00001593 decode_utimes(tcp, 1, 1);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001594 tprints(", ");
Dmitry V. Levin7989ad42012-03-13 23:26:01 +00001595 printflags(at_flags, tcp->u_arg[3], "AT_???");
Roland McGrath6afc5652007-07-24 01:57:11 +00001596 }
1597 return 0;
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001598}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001599
1600int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001601sys_utime(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001602{
Roland McGrath7e9817c2007-07-05 20:31:58 +00001603 union {
1604 long utl[2];
1605 int uti[2];
Denys Vlasenko751acb32013-02-08 15:34:46 +01001606 long paranoia_for_huge_wordsize[4];
Roland McGrath7e9817c2007-07-05 20:31:58 +00001607 } u;
Denys Vlasenko751acb32013-02-08 15:34:46 +01001608 unsigned wordsize;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001609
1610 if (entering(tcp)) {
1611 printpath(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001612 tprints(", ");
Denys Vlasenko751acb32013-02-08 15:34:46 +01001613
1614 wordsize = current_wordsize;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001615 if (!tcp->u_arg[1])
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001616 tprints("NULL");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001617 else if (!verbose(tcp))
1618 tprintf("%#lx", tcp->u_arg[1]);
Denys Vlasenko1945ccc2012-02-27 14:37:48 +01001619 else if (umoven(tcp, tcp->u_arg[1], 2 * wordsize, (char *) &u) < 0)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001620 tprints("[?, ?]");
Denys Vlasenko1945ccc2012-02-27 14:37:48 +01001621 else if (wordsize == sizeof u.utl[0]) {
Roland McGrath7e9817c2007-07-05 20:31:58 +00001622 tprintf("[%s,", sprinttime(u.utl[0]));
1623 tprintf(" %s]", sprinttime(u.utl[1]));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001624 }
Denys Vlasenko1945ccc2012-02-27 14:37:48 +01001625 else if (wordsize == sizeof u.uti[0]) {
Roland McGrath7e9817c2007-07-05 20:31:58 +00001626 tprintf("[%s,", sprinttime(u.uti[0]));
1627 tprintf(" %s]", sprinttime(u.uti[1]));
1628 }
1629 else
Denys Vlasenko751acb32013-02-08 15:34:46 +01001630 tprintf("<decode error: unsupported wordsize %d>",
1631 wordsize);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001632 }
1633 return 0;
1634}
1635
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001636static int
1637decode_mknod(struct tcb *tcp, int offset)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001638{
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001639 int mode = tcp->u_arg[offset + 1];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001640
1641 if (entering(tcp)) {
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001642 printpath(tcp, tcp->u_arg[offset]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001643 tprintf(", %s", sprintmode(mode));
1644 switch (mode & S_IFMT) {
Denys Vlasenkob237b1b2012-02-27 13:56:59 +01001645 case S_IFCHR:
1646 case S_IFBLK:
Denys Vlasenko9472a272013-02-12 11:43:46 +01001647#if defined(SPARC) || defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001648 if (current_personality == 1)
Denys Vlasenkob237b1b2012-02-27 13:56:59 +01001649 tprintf(", makedev(%lu, %lu)",
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001650 (unsigned long) ((tcp->u_arg[offset + 2] >> 18) & 0x3fff),
1651 (unsigned long) (tcp->u_arg[offset + 2] & 0x3ffff));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001652 else
Roland McGrath186c5ac2002-12-15 23:58:23 +00001653#endif
Denys Vlasenkob237b1b2012-02-27 13:56:59 +01001654 tprintf(", makedev(%lu, %lu)",
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001655 (unsigned long) major(tcp->u_arg[offset + 2]),
1656 (unsigned long) minor(tcp->u_arg[offset + 2]));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001657 break;
1658 default:
1659 break;
1660 }
1661 }
1662 return 0;
1663}
1664
1665int
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001666sys_mknod(struct tcb *tcp)
1667{
1668 return decode_mknod(tcp, 0);
1669}
1670
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001671int
1672sys_mknodat(struct tcb *tcp)
1673{
1674 if (entering(tcp))
Dmitry V. Levin31382132011-03-04 05:08:02 +03001675 print_dirfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001676 return decode_mknod(tcp, 1);
1677}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001678
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001679int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001680sys_getcwd(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001681{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001682 if (exiting(tcp)) {
1683 if (syserror(tcp))
1684 tprintf("%#lx", tcp->u_arg[0]);
1685 else
1686 printpathn(tcp, tcp->u_arg[0], tcp->u_rval - 1);
1687 tprintf(", %lu", tcp->u_arg[1]);
1688 }
1689 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001690}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001691
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +00001692#include "xlat/xattrflags.h"
Roland McGrath186c5ac2002-12-15 23:58:23 +00001693
Roland McGrath3292e222004-08-31 06:30:48 +00001694static void
Denys Vlasenko1d632462009-04-14 12:51:00 +00001695print_xattr_val(struct tcb *tcp, int failed,
1696 unsigned long arg,
1697 unsigned long insize,
1698 unsigned long size)
Roland McGrath3292e222004-08-31 06:30:48 +00001699{
Dmitry V. Levin1f215132012-12-07 21:38:52 +00001700 if (insize == 0)
1701 failed = 1;
Denys Vlasenko1d632462009-04-14 12:51:00 +00001702 if (!failed) {
1703 unsigned long capacity = 4 * size + 1;
1704 unsigned char *buf = (capacity < size) ? NULL : malloc(capacity);
1705 if (buf == NULL || /* probably a bogus size argument */
1706 umoven(tcp, arg, size, (char *) &buf[3 * size]) < 0) {
1707 failed = 1;
Roland McGrath883567c2005-02-02 03:38:32 +00001708 }
Denys Vlasenko1d632462009-04-14 12:51:00 +00001709 else {
1710 unsigned char *out = buf;
1711 unsigned char *in = &buf[3 * size];
1712 size_t i;
1713 for (i = 0; i < size; ++i) {
Denys Vlasenko5198ed42013-03-06 23:44:23 +01001714 if (in[i] >= ' ' && in[i] <= 0x7e)
Denys Vlasenko1d632462009-04-14 12:51:00 +00001715 *out++ = in[i];
1716 else {
1717#define tohex(n) "0123456789abcdef"[n]
1718 *out++ = '\\';
1719 *out++ = 'x';
1720 *out++ = tohex(in[i] / 16);
1721 *out++ = tohex(in[i] % 16);
1722 }
1723 }
1724 /* Don't print terminating NUL if there is one. */
1725 if (i > 0 && in[i - 1] == '\0')
1726 out -= 4;
1727 *out = '\0';
1728 tprintf(", \"%s\", %ld", buf, insize);
1729 }
1730 free(buf);
Roland McGrath883567c2005-02-02 03:38:32 +00001731 }
Denys Vlasenko1d632462009-04-14 12:51:00 +00001732 if (failed)
1733 tprintf(", 0x%lx, %ld", arg, insize);
Roland McGrath3292e222004-08-31 06:30:48 +00001734}
1735
Roland McGrath186c5ac2002-12-15 23:58:23 +00001736int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001737sys_setxattr(struct tcb *tcp)
Roland McGrath186c5ac2002-12-15 23:58:23 +00001738{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001739 if (entering(tcp)) {
1740 printpath(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001741 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +00001742 printstr(tcp, tcp->u_arg[1], -1);
1743 print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001744 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +00001745 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
1746 }
1747 return 0;
Roland McGrath186c5ac2002-12-15 23:58:23 +00001748}
1749
1750int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001751sys_fsetxattr(struct tcb *tcp)
Roland McGrath186c5ac2002-12-15 23:58:23 +00001752{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001753 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +03001754 printfd(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001755 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +00001756 printstr(tcp, tcp->u_arg[1], -1);
1757 print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001758 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +00001759 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
1760 }
1761 return 0;
Roland McGrath186c5ac2002-12-15 23:58:23 +00001762}
1763
1764int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001765sys_getxattr(struct tcb *tcp)
Roland McGrath186c5ac2002-12-15 23:58:23 +00001766{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001767 if (entering(tcp)) {
1768 printpath(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001769 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +00001770 printstr(tcp, tcp->u_arg[1], -1);
1771 } else {
1772 print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
1773 tcp->u_rval);
1774 }
1775 return 0;
Roland McGrath186c5ac2002-12-15 23:58:23 +00001776}
1777
1778int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001779sys_fgetxattr(struct tcb *tcp)
Roland McGrath186c5ac2002-12-15 23:58:23 +00001780{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001781 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +03001782 printfd(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001783 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +00001784 printstr(tcp, tcp->u_arg[1], -1);
1785 } else {
1786 print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
1787 tcp->u_rval);
1788 }
1789 return 0;
Roland McGrath186c5ac2002-12-15 23:58:23 +00001790}
1791
Dmitry V. Levin33d24762012-03-14 16:34:32 +00001792static void
1793print_xattr_list(struct tcb *tcp, unsigned long addr, unsigned long size)
1794{
1795 if (syserror(tcp)) {
1796 tprintf("%#lx", addr);
1797 } else {
1798 if (!addr) {
1799 tprints("NULL");
1800 } else {
1801 unsigned long len =
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +00001802 (size < (unsigned long) tcp->u_rval) ?
1803 size : (unsigned long) tcp->u_rval;
Dmitry V. Levin33d24762012-03-14 16:34:32 +00001804 printstr(tcp, addr, len);
1805 }
1806 }
1807 tprintf(", %lu", size);
1808}
1809
Roland McGrath186c5ac2002-12-15 23:58:23 +00001810int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001811sys_listxattr(struct tcb *tcp)
Roland McGrath186c5ac2002-12-15 23:58:23 +00001812{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001813 if (entering(tcp)) {
1814 printpath(tcp, tcp->u_arg[0]);
Dmitry V. Levin33d24762012-03-14 16:34:32 +00001815 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +00001816 } else {
Dmitry V. Levin33d24762012-03-14 16:34:32 +00001817 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]);
Denys Vlasenko1d632462009-04-14 12:51:00 +00001818 }
1819 return 0;
Roland McGrath186c5ac2002-12-15 23:58:23 +00001820}
1821
1822int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001823sys_flistxattr(struct tcb *tcp)
Roland McGrath186c5ac2002-12-15 23:58:23 +00001824{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001825 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +03001826 printfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin33d24762012-03-14 16:34:32 +00001827 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +00001828 } else {
Dmitry V. Levin33d24762012-03-14 16:34:32 +00001829 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]);
Denys Vlasenko1d632462009-04-14 12:51:00 +00001830 }
1831 return 0;
Roland McGrath186c5ac2002-12-15 23:58:23 +00001832}
1833
1834int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001835sys_removexattr(struct tcb *tcp)
Roland McGrath186c5ac2002-12-15 23:58:23 +00001836{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001837 if (entering(tcp)) {
1838 printpath(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001839 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +00001840 printstr(tcp, tcp->u_arg[1], -1);
1841 }
1842 return 0;
Roland McGrath186c5ac2002-12-15 23:58:23 +00001843}
1844
1845int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001846sys_fremovexattr(struct tcb *tcp)
Roland McGrath186c5ac2002-12-15 23:58:23 +00001847{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001848 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +03001849 printfd(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001850 tprints(", ");
Denys Vlasenko1d632462009-04-14 12:51:00 +00001851 printstr(tcp, tcp->u_arg[1], -1);
1852 }
1853 return 0;
Roland McGrath186c5ac2002-12-15 23:58:23 +00001854}
Roland McGrathdf13e8f2004-10-07 18:51:19 +00001855
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +00001856#include "xlat/advise.h"
Roland McGrathdf13e8f2004-10-07 18:51:19 +00001857
Roland McGrathdf13e8f2004-10-07 18:51:19 +00001858int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001859sys_fadvise64(struct tcb *tcp)
Roland McGrathdf13e8f2004-10-07 18:51:19 +00001860{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001861 if (entering(tcp)) {
Andreas Schwabb5600fc2009-11-04 17:08:34 +01001862 int argn;
Dmitry V. Levin31382132011-03-04 05:08:02 +03001863 printfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin3c49b022014-08-07 00:07:28 +00001864 argn = printllval(tcp, ", %lld", 1);
Andreas Schwabb5600fc2009-11-04 17:08:34 +01001865 tprintf(", %ld, ", tcp->u_arg[argn++]);
1866 printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???");
Denys Vlasenko1d632462009-04-14 12:51:00 +00001867 }
1868 return 0;
Roland McGrathdf13e8f2004-10-07 18:51:19 +00001869}
Roland McGrathdf13e8f2004-10-07 18:51:19 +00001870
Roland McGrathdf13e8f2004-10-07 18:51:19 +00001871int
Denys Vlasenko1d632462009-04-14 12:51:00 +00001872sys_fadvise64_64(struct tcb *tcp)
Roland McGrathdf13e8f2004-10-07 18:51:19 +00001873{
Denys Vlasenko1d632462009-04-14 12:51:00 +00001874 if (entering(tcp)) {
Andreas Schwabb5600fc2009-11-04 17:08:34 +01001875 int argn;
Dmitry V. Levin31382132011-03-04 05:08:02 +03001876 printfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin3c49b022014-08-07 00:07:28 +00001877 argn = printllval(tcp, ", %lld, ", 1);
1878 argn = printllval(tcp, "%lld, ", argn);
Dmitry V. Levin8e096c42013-05-06 18:23:01 +00001879#if defined __ARM_EABI__ || defined AARCH64 || defined POWERPC || defined XTENSA
Kirill A. Shutemov896db212009-09-19 03:21:33 +03001880 printxval(advise, tcp->u_arg[1], "POSIX_FADV_???");
Roland McGrathdf13e8f2004-10-07 18:51:19 +00001881#else
Andreas Schwabb5600fc2009-11-04 17:08:34 +01001882 printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???");
Roland McGrathdf13e8f2004-10-07 18:51:19 +00001883#endif
Denys Vlasenko1d632462009-04-14 12:51:00 +00001884 }
1885 return 0;
Roland McGrathdf13e8f2004-10-07 18:51:19 +00001886}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +00001887
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +00001888#include "xlat/sync_file_range_flags.h"
William Manley16b9dcf2013-08-09 18:04:11 +01001889
1890int
1891sys_sync_file_range(struct tcb *tcp)
1892{
1893 if (entering(tcp)) {
1894 int argn;
1895 printfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin3c49b022014-08-07 00:07:28 +00001896 argn = printllval(tcp, ", %lld, ", 1);
1897 argn = printllval(tcp, "%lld, ", argn);
William Manley16b9dcf2013-08-09 18:04:11 +01001898 printflags(sync_file_range_flags, tcp->u_arg[argn],
1899 "SYNC_FILE_RANGE_???");
1900 }
1901 return 0;
1902}
1903
1904int
1905sys_sync_file_range2(struct tcb *tcp)
1906{
1907 if (entering(tcp)) {
1908 int argn;
1909 printfd(tcp, tcp->u_arg[0]);
1910 printflags(sync_file_range_flags, 1,
1911 "SYNC_FILE_RANGE_???");
Dmitry V. Levin3c49b022014-08-07 00:07:28 +00001912 argn = printllval(tcp, ", %lld, ", 2);
1913 argn = printllval(tcp, "%lld, ", argn);
William Manley16b9dcf2013-08-09 18:04:11 +01001914 }
1915 return 0;
1916}
1917
Mark Wielaardbab89402010-03-21 14:41:26 +01001918int
Roland McGrath96a96612008-05-20 04:56:18 +00001919sys_fallocate(struct tcb *tcp)
1920{
1921 if (entering(tcp)) {
Andreas Schwabb5600fc2009-11-04 17:08:34 +01001922 int argn;
Dmitry V. Levin31382132011-03-04 05:08:02 +03001923 printfd(tcp, tcp->u_arg[0]); /* fd */
Denys Vlasenkod33e72a2012-05-18 02:03:24 +02001924 tprintf(", %#lo, ", tcp->u_arg[1]); /* mode */
Dmitry V. Levin3c49b022014-08-07 00:07:28 +00001925 argn = printllval(tcp, "%llu, ", 2); /* offset */
1926 printllval(tcp, "%llu", argn); /* len */
Roland McGrath96a96612008-05-20 04:56:18 +00001927 }
1928 return 0;
1929}
Dmitry V. Levin88293652012-03-09 21:02:19 +00001930
Dmitry V. Levinad0c01e2012-03-15 00:52:22 +00001931#ifndef SWAP_FLAG_PREFER
1932# define SWAP_FLAG_PREFER 0x8000
1933#endif
1934#ifndef SWAP_FLAG_DISCARD
1935# define SWAP_FLAG_DISCARD 0x10000
1936#endif
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +00001937#include "xlat/swap_flags.h"
Dmitry V. Levin88293652012-03-09 21:02:19 +00001938
1939int
1940sys_swapon(struct tcb *tcp)
1941{
1942 if (entering(tcp)) {
1943 int flags = tcp->u_arg[1];
1944 printpath(tcp, tcp->u_arg[0]);
1945 tprints(", ");
1946 printflags(swap_flags, flags & ~SWAP_FLAG_PRIO_MASK,
1947 "SWAP_FLAG_???");
1948 if (flags & SWAP_FLAG_PREFER)
1949 tprintf("|%d", flags & SWAP_FLAG_PRIO_MASK);
1950 }
1951 return 0;
1952}