]> granicus.if.org Git - strace/blob - file.c
file.c: move chdir parser to a separate file
[strace] / file.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "defs.h"
32
33 #if defined(SPARC) || defined(SPARC64)
34 struct stat {
35         unsigned short  st_dev;
36         unsigned int    st_ino;
37         unsigned short  st_mode;
38         short           st_nlink;
39         unsigned short  st_uid;
40         unsigned short  st_gid;
41         unsigned short  st_rdev;
42         unsigned int    st_size;
43         int             st_atime;
44         unsigned int    __unused1;
45         int             st_mtime;
46         unsigned int    __unused2;
47         int             st_ctime;
48         unsigned int    __unused3;
49         int             st_blksize;
50         int             st_blocks;
51         unsigned int    __unused4[2];
52 };
53 # if defined(SPARC64)
54 struct stat_sparc64 {
55         unsigned int    st_dev;
56         unsigned long   st_ino;
57         unsigned int    st_mode;
58         unsigned int    st_nlink;
59         unsigned int    st_uid;
60         unsigned int    st_gid;
61         unsigned int    st_rdev;
62         long            st_size;
63         long            st_atime;
64         long            st_mtime;
65         long            st_ctime;
66         long            st_blksize;
67         long            st_blocks;
68         unsigned long   __unused4[2];
69 };
70 # endif /* SPARC64 */
71 # define stat kernel_stat
72 # include <asm/stat.h>
73 # undef stat
74 #elif defined(X32)
75 struct stat {
76         unsigned long long      st_dev;
77         unsigned long long      st_ino;
78         unsigned long long      st_nlink;
79
80         unsigned int            st_mode;
81         unsigned int            st_uid;
82         unsigned int            st_gid;
83         unsigned int            __pad0;
84         unsigned long long      st_rdev;
85         long long               st_size;
86         long long               st_blksize;
87         long long               st_blocks;
88
89         unsigned long long      st_atime;
90         unsigned long long      st_atime_nsec;
91         unsigned long long      st_mtime;
92         unsigned long long      st_mtime_nsec;
93         unsigned long long      st_ctime;
94         unsigned long long      st_ctime_nsec;
95         long long               __unused[3];
96 };
97
98 struct stat64 {
99         unsigned long long      st_dev;
100         unsigned char           __pad0[4];
101         unsigned long           __st_ino;
102         unsigned int            st_mode;
103         unsigned int            st_nlink;
104         unsigned long           st_uid;
105         unsigned long           st_gid;
106         unsigned long long      st_rdev;
107         unsigned char           __pad3[4];
108         long long               st_size;
109         unsigned long           st_blksize;
110         unsigned long long      st_blocks;
111         unsigned long           st_atime;
112         unsigned long           st_atime_nsec;
113         unsigned long           st_mtime;
114         unsigned int            st_mtime_nsec;
115         unsigned long           st_ctime;
116         unsigned long           st_ctime_nsec;
117         unsigned long long      st_ino;
118 } __attribute__((packed));
119 # define HAVE_STAT64    1
120
121 struct __old_kernel_stat {
122         unsigned short st_dev;
123         unsigned short st_ino;
124         unsigned short st_mode;
125         unsigned short st_nlink;
126         unsigned short st_uid;
127         unsigned short st_gid;
128         unsigned short st_rdev;
129         unsigned int   st_size;
130         unsigned int   st_atime;
131         unsigned int   st_mtime;
132         unsigned int   st_ctime;
133 };
134 #else
135 # undef dev_t
136 # undef ino_t
137 # undef mode_t
138 # undef nlink_t
139 # undef uid_t
140 # undef gid_t
141 # undef off_t
142 # undef loff_t
143 # define dev_t __kernel_dev_t
144 # define ino_t __kernel_ino_t
145 # define mode_t __kernel_mode_t
146 # define nlink_t __kernel_nlink_t
147 # define uid_t __kernel_uid_t
148 # define gid_t __kernel_gid_t
149 # define off_t __kernel_off_t
150 # define loff_t __kernel_loff_t
151
152 # include <asm/stat.h>
153
154 # undef dev_t
155 # undef ino_t
156 # undef mode_t
157 # undef nlink_t
158 # undef uid_t
159 # undef gid_t
160 # undef off_t
161 # undef loff_t
162 # define dev_t dev_t
163 # define ino_t ino_t
164 # define mode_t mode_t
165 # define nlink_t nlink_t
166 # define uid_t uid_t
167 # define gid_t gid_t
168 # define off_t off_t
169 # define loff_t loff_t
170 #endif
171
172 #define stat libc_stat
173 #define stat64 libc_stat64
174 #include <sys/stat.h>
175 #undef stat
176 #undef stat64
177 /* These might be macros. */
178 #undef st_atime
179 #undef st_mtime
180 #undef st_ctime
181
182 #include <fcntl.h>
183
184 #ifdef MAJOR_IN_SYSMACROS
185 # include <sys/sysmacros.h>
186 #endif
187
188 #ifdef MAJOR_IN_MKDEV
189 # include <sys/mkdev.h>
190 #endif
191
192 #ifdef O_LARGEFILE
193 # if O_LARGEFILE == 0          /* biarch platforms in 64-bit mode */
194 #  undef O_LARGEFILE
195 #  ifdef SPARC64
196 #   define O_LARGEFILE 0x40000
197 #  elif defined X86_64 || defined S390X
198 #   define O_LARGEFILE 0100000
199 #  endif
200 # endif
201 #endif
202
203 #include "xlat/open_access_modes.h"
204 #include "xlat/open_mode_flags.h"
205
206 #ifndef AT_FDCWD
207 # define AT_FDCWD                -100
208 #endif
209
210 /* The fd is an "int", so when decoding x86 on x86_64, we need to force sign
211  * extension to get the right value.  We do this by declaring fd as int here.
212  */
213 void
214 print_dirfd(struct tcb *tcp, int fd)
215 {
216         if (fd == AT_FDCWD)
217                 tprints("AT_FDCWD, ");
218         else {
219                 printfd(tcp, fd);
220                 tprints(", ");
221         }
222 }
223
224 /*
225  * low bits of the open(2) flags define access mode,
226  * other bits are real flags.
227  */
228 const char *
229 sprint_open_modes(int flags)
230 {
231         static char outstr[(1 + ARRAY_SIZE(open_mode_flags)) * sizeof("O_LARGEFILE")];
232         char *p;
233         char sep;
234         const char *str;
235         const struct xlat *x;
236
237         sep = ' ';
238         p = stpcpy(outstr, "flags");
239         str = xlookup(open_access_modes, flags & 3);
240         if (str) {
241                 *p++ = sep;
242                 p = stpcpy(p, str);
243                 flags &= ~3;
244                 if (!flags)
245                         return outstr;
246                 sep = '|';
247         }
248
249         for (x = open_mode_flags; x->str; x++) {
250                 if ((flags & x->val) == x->val) {
251                         *p++ = sep;
252                         p = stpcpy(p, x->str);
253                         flags &= ~x->val;
254                         if (!flags)
255                                 return outstr;
256                         sep = '|';
257                 }
258         }
259         /* flags is still nonzero */
260         *p++ = sep;
261         sprintf(p, "%#x", flags);
262         return outstr;
263 }
264
265 void
266 tprint_open_modes(int flags)
267 {
268         tprints(sprint_open_modes(flags) + sizeof("flags"));
269 }
270
271 static int
272 decode_open(struct tcb *tcp, int offset)
273 {
274         if (entering(tcp)) {
275                 printpath(tcp, tcp->u_arg[offset]);
276                 tprints(", ");
277                 /* flags */
278                 tprint_open_modes(tcp->u_arg[offset + 1]);
279                 if (tcp->u_arg[offset + 1] & O_CREAT) {
280                         /* mode */
281                         tprintf(", %#lo", tcp->u_arg[offset + 2]);
282                 }
283         }
284         return RVAL_FD;
285 }
286
287 int
288 sys_open(struct tcb *tcp)
289 {
290         return decode_open(tcp, 0);
291 }
292
293 int
294 sys_openat(struct tcb *tcp)
295 {
296         if (entering(tcp))
297                 print_dirfd(tcp, tcp->u_arg[0]);
298         return decode_open(tcp, 1);
299 }
300
301 #if defined(SPARC) || defined(SPARC64)
302 #include "xlat/openmodessol.h"
303
304 int
305 solaris_open(struct tcb *tcp)
306 {
307         if (entering(tcp)) {
308                 printpath(tcp, tcp->u_arg[0]);
309                 tprints(", ");
310                 /* flags */
311                 printflags(openmodessol, tcp->u_arg[1] + 1, "O_???");
312                 if (tcp->u_arg[1] & 0x100) {
313                         /* mode */
314                         tprintf(", %#lo", tcp->u_arg[2]);
315                 }
316         }
317         return 0;
318 }
319
320 #endif
321
322 int
323 sys_creat(struct tcb *tcp)
324 {
325         if (entering(tcp)) {
326                 printpath(tcp, tcp->u_arg[0]);
327                 tprintf(", %#lo", tcp->u_arg[1]);
328         }
329         return RVAL_FD;
330 }
331
332 #include "xlat/access_flags.h"
333
334 static int
335 decode_access(struct tcb *tcp, int offset)
336 {
337         if (entering(tcp)) {
338                 printpath(tcp, tcp->u_arg[offset]);
339                 tprints(", ");
340                 printflags(access_flags, tcp->u_arg[offset + 1], "?_OK");
341         }
342         return 0;
343 }
344
345 int
346 sys_access(struct tcb *tcp)
347 {
348         return decode_access(tcp, 0);
349 }
350
351 int
352 sys_faccessat(struct tcb *tcp)
353 {
354         if (entering(tcp))
355                 print_dirfd(tcp, tcp->u_arg[0]);
356         return decode_access(tcp, 1);
357 }
358
359 int
360 sys_umask(struct tcb *tcp)
361 {
362         if (entering(tcp)) {
363                 tprintf("%#lo", tcp->u_arg[0]);
364         }
365         return RVAL_OCTAL;
366 }
367
368 #include "xlat/whence_codes.h"
369
370 /* Linux kernel has exactly one version of lseek:
371  * fs/read_write.c::SYSCALL_DEFINE3(lseek, unsigned, fd, off_t, offset, unsigned, origin)
372  * In kernel, off_t is always the same as (kernel's) long
373  * (see include/uapi/asm-generic/posix_types.h),
374  * which means that on x32 we need to use tcp->ext_arg[N] to get offset argument.
375  * Use test/x32_lseek.c to test lseek decoding.
376  */
377 #if defined(LINUX_MIPSN32) || defined(X32)
378 int
379 sys_lseek(struct tcb *tcp)
380 {
381         long long offset;
382         int whence;
383
384         if (entering(tcp)) {
385                 printfd(tcp, tcp->u_arg[0]);
386                 offset = tcp->ext_arg[1];
387                 whence = tcp->u_arg[2];
388                 if (whence == SEEK_SET)
389                         tprintf(", %llu, ", offset);
390                 else
391                         tprintf(", %lld, ", offset);
392                 printxval(whence_codes, whence, "SEEK_???");
393         }
394         return RVAL_LUDECIMAL;
395 }
396 #else
397 int
398 sys_lseek(struct tcb *tcp)
399 {
400         long offset;
401         int whence;
402
403         if (entering(tcp)) {
404                 printfd(tcp, tcp->u_arg[0]);
405                 offset = tcp->u_arg[1];
406                 whence = tcp->u_arg[2];
407                 if (whence == SEEK_SET)
408                         tprintf(", %lu, ", offset);
409                 else
410                         tprintf(", %ld, ", offset);
411                 printxval(whence_codes, whence, "SEEK_???");
412         }
413         return RVAL_UDECIMAL;
414 }
415 #endif
416
417 /* llseek syscall takes explicitly two ulong arguments hi, lo,
418  * rather than one 64-bit argument for which LONG_LONG works
419  * appropriate for the native byte order.
420  *
421  * See kernel's fs/read_write.c::SYSCALL_DEFINE5(llseek, ...)
422  *
423  * hi,lo are "unsigned longs" and combined exactly this way in kernel:
424  * ((loff_t) hi << 32) | lo
425  * Note that for architectures with kernel's long wider than userspace long
426  * (such as x32), combining code will use *kernel's*, i.e. *wide* longs
427  * for hi and lo. We would need to use tcp->ext_arg[N] on x32...
428  * ...however, x32 (and x86_64) does not _have_ llseek syscall as such.
429  */
430 int
431 sys_llseek(struct tcb *tcp)
432 {
433         if (entering(tcp)) {
434                 printfd(tcp, tcp->u_arg[0]);
435                 if (tcp->u_arg[4] == SEEK_SET)
436                         tprintf(", %llu, ",
437                                 ((long long) tcp->u_arg[1]) << 32 |
438                                 (unsigned long long) (unsigned) tcp->u_arg[2]);
439                 else
440                         tprintf(", %lld, ",
441                                 ((long long) tcp->u_arg[1]) << 32 |
442                                 (unsigned long long) (unsigned) tcp->u_arg[2]);
443         }
444         else {
445                 long long off;
446                 if (syserror(tcp) || umove(tcp, tcp->u_arg[3], &off) < 0)
447                         tprintf("%#lx, ", tcp->u_arg[3]);
448                 else
449                         tprintf("[%llu], ", off);
450                 printxval(whence_codes, tcp->u_arg[4], "SEEK_???");
451         }
452         return 0;
453 }
454
455 int
456 sys_readahead(struct tcb *tcp)
457 {
458         if (entering(tcp)) {
459                 int argn;
460                 printfd(tcp, tcp->u_arg[0]);
461                 argn = printllval(tcp, ", %lld", 1);
462                 tprintf(", %ld", tcp->u_arg[argn]);
463         }
464         return 0;
465 }
466
467 int
468 sys_truncate(struct tcb *tcp)
469 {
470         if (entering(tcp)) {
471                 printpath(tcp, tcp->u_arg[0]);
472                 tprintf(", %lu", tcp->u_arg[1]);
473         }
474         return 0;
475 }
476
477 int
478 sys_truncate64(struct tcb *tcp)
479 {
480         if (entering(tcp)) {
481                 printpath(tcp, tcp->u_arg[0]);
482                 printllval(tcp, ", %llu", 1);
483         }
484         return 0;
485 }
486
487 int
488 sys_ftruncate(struct tcb *tcp)
489 {
490         if (entering(tcp)) {
491                 printfd(tcp, tcp->u_arg[0]);
492                 tprintf(", %lu", tcp->u_arg[1]);
493         }
494         return 0;
495 }
496
497 int
498 sys_ftruncate64(struct tcb *tcp)
499 {
500         if (entering(tcp)) {
501                 printfd(tcp, tcp->u_arg[0]);
502                 printllval(tcp, ", %llu", 1);
503         }
504         return 0;
505 }
506
507 /* several stats */
508
509 #if defined(SPARC) || defined(SPARC64)
510 typedef struct {
511         int     tv_sec;
512         int     tv_nsec;
513 } timestruct_t;
514
515 struct solstat {
516         unsigned        st_dev;
517         int             st_pad1[3];     /* network id */
518         unsigned        st_ino;
519         unsigned        st_mode;
520         unsigned        st_nlink;
521         unsigned        st_uid;
522         unsigned        st_gid;
523         unsigned        st_rdev;
524         int             st_pad2[2];
525         int             st_size;
526         int             st_pad3;        /* st_size, off_t expansion */
527         timestruct_t    st_atime;
528         timestruct_t    st_mtime;
529         timestruct_t    st_ctime;
530         int             st_blksize;
531         int             st_blocks;
532         char            st_fstype[16];
533         int             st_pad4[8];     /* expansion area */
534 };
535
536 static void
537 printstatsol(struct tcb *tcp, long addr)
538 {
539         struct solstat statbuf;
540
541         if (umove(tcp, addr, &statbuf) < 0) {
542                 tprints("{...}");
543                 return;
544         }
545         if (!abbrev(tcp)) {
546                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
547                         (unsigned long) ((statbuf.st_dev >> 18) & 0x3fff),
548                         (unsigned long) (statbuf.st_dev & 0x3ffff),
549                         (unsigned long) statbuf.st_ino,
550                         sprintmode(statbuf.st_mode));
551                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
552                         (unsigned long) statbuf.st_nlink,
553                         (unsigned long) statbuf.st_uid,
554                         (unsigned long) statbuf.st_gid);
555                 tprintf("st_blksize=%lu, ", (unsigned long) statbuf.st_blksize);
556                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
557         }
558         else
559                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
560         switch (statbuf.st_mode & S_IFMT) {
561         case S_IFCHR: case S_IFBLK:
562                 tprintf("st_rdev=makedev(%lu, %lu), ",
563                         (unsigned long) ((statbuf.st_rdev >> 18) & 0x3fff),
564                         (unsigned long) (statbuf.st_rdev & 0x3ffff));
565                 break;
566         default:
567                 tprintf("st_size=%u, ", statbuf.st_size);
568                 break;
569         }
570         if (!abbrev(tcp)) {
571                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime.tv_sec));
572                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime.tv_sec));
573                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime.tv_sec));
574         }
575         else
576                 tprints("...}");
577 }
578
579 # if defined(SPARC64)
580 static void
581 printstat_sparc64(struct tcb *tcp, long addr)
582 {
583         struct stat_sparc64 statbuf;
584
585         if (umove(tcp, addr, &statbuf) < 0) {
586                 tprints("{...}");
587                 return;
588         }
589
590         if (!abbrev(tcp)) {
591                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
592                         (unsigned long) major(statbuf.st_dev),
593                         (unsigned long) minor(statbuf.st_dev),
594                         (unsigned long) statbuf.st_ino,
595                         sprintmode(statbuf.st_mode));
596                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
597                         (unsigned long) statbuf.st_nlink,
598                         (unsigned long) statbuf.st_uid,
599                         (unsigned long) statbuf.st_gid);
600                 tprintf("st_blksize=%lu, ",
601                         (unsigned long) statbuf.st_blksize);
602                 tprintf("st_blocks=%lu, ",
603                         (unsigned long) statbuf.st_blocks);
604         }
605         else
606                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
607         switch (statbuf.st_mode & S_IFMT) {
608         case S_IFCHR: case S_IFBLK:
609                 tprintf("st_rdev=makedev(%lu, %lu), ",
610                         (unsigned long) major(statbuf.st_rdev),
611                         (unsigned long) minor(statbuf.st_rdev));
612                 break;
613         default:
614                 tprintf("st_size=%lu, ", statbuf.st_size);
615                 break;
616         }
617         if (!abbrev(tcp)) {
618                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
619                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
620                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
621         }
622         else
623                 tprints("...}");
624 }
625 # endif /* SPARC64 */
626 #endif /* SPARC[64] */
627
628 #if defined POWERPC64
629 struct stat_powerpc32 {
630         unsigned int    st_dev;
631         unsigned int    st_ino;
632         unsigned int    st_mode;
633         unsigned short  st_nlink;
634         unsigned int    st_uid;
635         unsigned int    st_gid;
636         unsigned int    st_rdev;
637         unsigned int    st_size;
638         unsigned int    st_blksize;
639         unsigned int    st_blocks;
640         unsigned int    st_atime;
641         unsigned int    st_atime_nsec;
642         unsigned int    st_mtime;
643         unsigned int    st_mtime_nsec;
644         unsigned int    st_ctime;
645         unsigned int    st_ctime_nsec;
646         unsigned int    __unused4;
647         unsigned int    __unused5;
648 };
649
650 static void
651 printstat_powerpc32(struct tcb *tcp, long addr)
652 {
653         struct stat_powerpc32 statbuf;
654
655         if (umove(tcp, addr, &statbuf) < 0) {
656                 tprints("{...}");
657                 return;
658         }
659
660         if (!abbrev(tcp)) {
661                 tprintf("{st_dev=makedev(%u, %u), st_ino=%u, st_mode=%s, ",
662                         major(statbuf.st_dev), minor(statbuf.st_dev),
663                         statbuf.st_ino,
664                         sprintmode(statbuf.st_mode));
665                 tprintf("st_nlink=%u, st_uid=%u, st_gid=%u, ",
666                         statbuf.st_nlink, statbuf.st_uid, statbuf.st_gid);
667                 tprintf("st_blksize=%u, ", statbuf.st_blksize);
668                 tprintf("st_blocks=%u, ", statbuf.st_blocks);
669         }
670         else
671                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
672         switch (statbuf.st_mode & S_IFMT) {
673         case S_IFCHR: case S_IFBLK:
674                 tprintf("st_rdev=makedev(%lu, %lu), ",
675                         (unsigned long) major(statbuf.st_rdev),
676                         (unsigned long) minor(statbuf.st_rdev));
677                 break;
678         default:
679                 tprintf("st_size=%u, ", statbuf.st_size);
680                 break;
681         }
682         if (!abbrev(tcp)) {
683                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
684                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
685                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
686         }
687         else
688                 tprints("...}");
689 }
690 #endif /* POWERPC64 */
691
692 #include "xlat/fileflags.h"
693
694 static void
695 realprintstat(struct tcb *tcp, struct stat *statbuf)
696 {
697         if (!abbrev(tcp)) {
698                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
699                         (unsigned long) major(statbuf->st_dev),
700                         (unsigned long) minor(statbuf->st_dev),
701                         (unsigned long) statbuf->st_ino,
702                         sprintmode(statbuf->st_mode));
703                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
704                         (unsigned long) statbuf->st_nlink,
705                         (unsigned long) statbuf->st_uid,
706                         (unsigned long) statbuf->st_gid);
707 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
708                 tprintf("st_blksize=%lu, ", (unsigned long) statbuf->st_blksize);
709 #endif
710 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
711                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf->st_blocks);
712 #endif
713         }
714         else
715                 tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode));
716         switch (statbuf->st_mode & S_IFMT) {
717         case S_IFCHR: case S_IFBLK:
718 #ifdef HAVE_STRUCT_STAT_ST_RDEV
719                 tprintf("st_rdev=makedev(%lu, %lu), ",
720                         (unsigned long) major(statbuf->st_rdev),
721                         (unsigned long) minor(statbuf->st_rdev));
722 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
723                 tprintf("st_size=makedev(%lu, %lu), ",
724                         (unsigned long) major(statbuf->st_size),
725                         (unsigned long) minor(statbuf->st_size));
726 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
727                 break;
728         default:
729                 tprintf("st_size=%lu, ", (unsigned long) statbuf->st_size);
730                 break;
731         }
732         if (!abbrev(tcp)) {
733                 tprintf("st_atime=%s, ", sprinttime(statbuf->st_atime));
734                 tprintf("st_mtime=%s, ", sprinttime(statbuf->st_mtime));
735                 tprintf("st_ctime=%s", sprinttime(statbuf->st_ctime));
736 #if HAVE_STRUCT_STAT_ST_FLAGS
737                 tprints(", st_flags=");
738                 printflags(fileflags, statbuf->st_flags, "UF_???");
739 #endif
740 #if HAVE_STRUCT_STAT_ST_ACLCNT
741                 tprintf(", st_aclcnt=%d", statbuf->st_aclcnt);
742 #endif
743 #if HAVE_STRUCT_STAT_ST_LEVEL
744                 tprintf(", st_level=%ld", statbuf->st_level);
745 #endif
746 #if HAVE_STRUCT_STAT_ST_FSTYPE
747                 tprintf(", st_fstype=%.*s",
748                         (int) sizeof statbuf->st_fstype, statbuf->st_fstype);
749 #endif
750 #if HAVE_STRUCT_STAT_ST_GEN
751                 tprintf(", st_gen=%u", statbuf->st_gen);
752 #endif
753                 tprints("}");
754         }
755         else
756                 tprints("...}");
757 }
758
759 #ifndef X32
760 static void
761 printstat(struct tcb *tcp, long addr)
762 {
763         struct stat statbuf;
764
765         if (!addr) {
766                 tprints("NULL");
767                 return;
768         }
769         if (syserror(tcp) || !verbose(tcp)) {
770                 tprintf("%#lx", addr);
771                 return;
772         }
773
774 #if defined(SPARC) || defined(SPARC64)
775         if (current_personality == 1) {
776                 printstatsol(tcp, addr);
777                 return;
778         }
779 #ifdef SPARC64
780         else if (current_personality == 2) {
781                 printstat_sparc64(tcp, addr);
782                 return;
783         }
784 #endif
785 #endif /* SPARC[64] */
786
787 #if defined POWERPC64
788         if (current_personality == 1) {
789                 printstat_powerpc32(tcp, addr);
790                 return;
791         }
792 #endif
793
794         if (umove(tcp, addr, &statbuf) < 0) {
795                 tprints("{...}");
796                 return;
797         }
798
799         realprintstat(tcp, &statbuf);
800 }
801 #else /* X32 */
802 # define printstat printstat64
803 #endif
804
805 #if !defined HAVE_STAT64 && (defined AARCH64 || defined X86_64)
806 /*
807  * Linux x86_64 has unified `struct stat' but its i386 biarch needs
808  * `struct stat64'.  Its <asm-i386/stat.h> definition expects 32-bit `long'.
809  * <linux/include/asm-x86_64/ia32.h> is not in the public includes set.
810  * __GNUC__ is needed for the required __attribute__ below.
811  *
812  * Similarly, aarch64 has a unified `struct stat' but its arm personality
813  * needs `struct stat64' (which also expects a 32-bit `long' but which
814  * shouldn't be packed).
815  */
816 struct stat64 {
817         unsigned long long      st_dev;
818         unsigned char   __pad0[4];
819         unsigned int    __st_ino;
820         unsigned int    st_mode;
821         unsigned int    st_nlink;
822         unsigned int    st_uid;
823         unsigned int    st_gid;
824         unsigned long long      st_rdev;
825         unsigned char   __pad3[4];
826         long long       st_size;
827         unsigned int    st_blksize;
828         unsigned long long      st_blocks;
829         unsigned int    st_atime;
830         unsigned int    st_atime_nsec;
831         unsigned int    st_mtime;
832         unsigned int    st_mtime_nsec;
833         unsigned int    st_ctime;
834         unsigned int    st_ctime_nsec;
835         unsigned long long      st_ino;
836 }
837 # if defined X86_64
838    __attribute__((packed))
839 #  define STAT64_SIZE   96
840 #else
841 #  define STAT64_SIZE   104
842 # endif
843 ;
844 # define HAVE_STAT64    1
845 #endif
846
847 #ifdef HAVE_STAT64
848 static void
849 printstat64(struct tcb *tcp, long addr)
850 {
851 #ifdef X32
852         struct stat statbuf;
853 #else
854         struct stat64 statbuf;
855 #endif
856
857 #ifdef STAT64_SIZE
858         (void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
859 #endif
860
861         if (!addr) {
862                 tprints("NULL");
863                 return;
864         }
865         if (syserror(tcp) || !verbose(tcp)) {
866                 tprintf("%#lx", addr);
867                 return;
868         }
869
870 #if defined(SPARC) || defined(SPARC64)
871         if (current_personality == 1) {
872                 printstatsol(tcp, addr);
873                 return;
874         }
875 # ifdef SPARC64
876         else if (current_personality == 2) {
877                 printstat_sparc64(tcp, addr);
878                 return;
879         }
880 # endif
881 #endif /* SPARC[64] */
882
883 #if defined AARCH64
884         if (current_personality != 0) {
885                 printstat(tcp, addr);
886                 return;
887         }
888 #endif
889 #if defined X86_64
890         if (current_personality != 1) {
891                 printstat(tcp, addr);
892                 return;
893         }
894 #endif
895
896         if (umove(tcp, addr, &statbuf) < 0) {
897                 tprints("{...}");
898                 return;
899         }
900
901         if (!abbrev(tcp)) {
902                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
903                         (unsigned long) major(statbuf.st_dev),
904                         (unsigned long) minor(statbuf.st_dev),
905                         (unsigned long long) statbuf.st_ino,
906                         sprintmode(statbuf.st_mode));
907                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
908                         (unsigned long) statbuf.st_nlink,
909                         (unsigned long) statbuf.st_uid,
910                         (unsigned long) statbuf.st_gid);
911 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
912                 tprintf("st_blksize=%lu, ",
913                         (unsigned long) statbuf.st_blksize);
914 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
915 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
916                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
917 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
918         }
919         else
920                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
921         switch (statbuf.st_mode & S_IFMT) {
922         case S_IFCHR: case S_IFBLK:
923 #ifdef HAVE_STRUCT_STAT_ST_RDEV
924                 tprintf("st_rdev=makedev(%lu, %lu), ",
925                         (unsigned long) major(statbuf.st_rdev),
926                         (unsigned long) minor(statbuf.st_rdev));
927 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
928                 tprintf("st_size=makedev(%lu, %lu), ",
929                         (unsigned long) major(statbuf.st_size),
930                         (unsigned long) minor(statbuf.st_size));
931 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
932                 break;
933         default:
934                 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
935                 break;
936         }
937         if (!abbrev(tcp)) {
938                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
939                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
940                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
941 #if HAVE_STRUCT_STAT_ST_FLAGS
942                 tprints(", st_flags=");
943                 printflags(fileflags, statbuf.st_flags, "UF_???");
944 #endif
945 #if HAVE_STRUCT_STAT_ST_ACLCNT
946                 tprintf(", st_aclcnt=%d", statbuf.st_aclcnt);
947 #endif
948 #if HAVE_STRUCT_STAT_ST_LEVEL
949                 tprintf(", st_level=%ld", statbuf.st_level);
950 #endif
951 #if HAVE_STRUCT_STAT_ST_FSTYPE
952                 tprintf(", st_fstype=%.*s",
953                         (int) sizeof statbuf.st_fstype, statbuf.st_fstype);
954 #endif
955 #if HAVE_STRUCT_STAT_ST_GEN
956                 tprintf(", st_gen=%u", statbuf.st_gen);
957 #endif
958                 tprints("}");
959         }
960         else
961                 tprints("...}");
962 }
963 #endif /* HAVE_STAT64 */
964
965 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
966 static void
967 convertoldstat(const struct __old_kernel_stat *oldbuf, struct stat *newbuf)
968 {
969         newbuf->st_dev = oldbuf->st_dev;
970         newbuf->st_ino = oldbuf->st_ino;
971         newbuf->st_mode = oldbuf->st_mode;
972         newbuf->st_nlink = oldbuf->st_nlink;
973         newbuf->st_uid = oldbuf->st_uid;
974         newbuf->st_gid = oldbuf->st_gid;
975         newbuf->st_rdev = oldbuf->st_rdev;
976         newbuf->st_size = oldbuf->st_size;
977         newbuf->st_atime = oldbuf->st_atime;
978         newbuf->st_mtime = oldbuf->st_mtime;
979         newbuf->st_ctime = oldbuf->st_ctime;
980         newbuf->st_blksize = 0; /* not supported in old_stat */
981         newbuf->st_blocks = 0; /* not supported in old_stat */
982 }
983
984 static void
985 printoldstat(struct tcb *tcp, long addr)
986 {
987         struct __old_kernel_stat statbuf;
988         struct stat newstatbuf;
989
990         if (!addr) {
991                 tprints("NULL");
992                 return;
993         }
994         if (syserror(tcp) || !verbose(tcp)) {
995                 tprintf("%#lx", addr);
996                 return;
997         }
998
999 # if defined(SPARC) || defined(SPARC64)
1000         if (current_personality == 1) {
1001                 printstatsol(tcp, addr);
1002                 return;
1003         }
1004 # endif
1005
1006         if (umove(tcp, addr, &statbuf) < 0) {
1007                 tprints("{...}");
1008                 return;
1009         }
1010
1011         convertoldstat(&statbuf, &newstatbuf);
1012         realprintstat(tcp, &newstatbuf);
1013 }
1014 #endif
1015
1016 int
1017 sys_stat(struct tcb *tcp)
1018 {
1019         if (entering(tcp)) {
1020                 printpath(tcp, tcp->u_arg[0]);
1021                 tprints(", ");
1022         } else {
1023                 printstat(tcp, tcp->u_arg[1]);
1024         }
1025         return 0;
1026 }
1027
1028 #ifdef X32
1029 static void
1030 printstat64_x32(struct tcb *tcp, long addr)
1031 {
1032         struct stat64 statbuf;
1033
1034         if (!addr) {
1035                 tprints("NULL");
1036                 return;
1037         }
1038         if (syserror(tcp) || !verbose(tcp)) {
1039                 tprintf("%#lx", addr);
1040                 return;
1041         }
1042
1043         if (umove(tcp, addr, &statbuf) < 0) {
1044                 tprints("{...}");
1045                 return;
1046         }
1047
1048         if (!abbrev(tcp)) {
1049                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
1050                         (unsigned long) major(statbuf.st_dev),
1051                         (unsigned long) minor(statbuf.st_dev),
1052                         (unsigned long long) statbuf.st_ino,
1053                         sprintmode(statbuf.st_mode));
1054                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
1055                         (unsigned long) statbuf.st_nlink,
1056                         (unsigned long) statbuf.st_uid,
1057                         (unsigned long) statbuf.st_gid);
1058                 tprintf("st_blksize=%lu, ",
1059                         (unsigned long) statbuf.st_blksize);
1060                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
1061         }
1062         else
1063                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
1064         switch (statbuf.st_mode & S_IFMT) {
1065         case S_IFCHR: case S_IFBLK:
1066                 tprintf("st_rdev=makedev(%lu, %lu), ",
1067                         (unsigned long) major(statbuf.st_rdev),
1068                         (unsigned long) minor(statbuf.st_rdev));
1069                 break;
1070         default:
1071                 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
1072                 break;
1073         }
1074         if (!abbrev(tcp)) {
1075                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
1076                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
1077                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
1078                 tprints("}");
1079         }
1080         else
1081                 tprints("...}");
1082 }
1083 #endif /* X32 */
1084
1085 int
1086 sys_stat64(struct tcb *tcp)
1087 {
1088 #ifdef HAVE_STAT64
1089         if (entering(tcp)) {
1090                 printpath(tcp, tcp->u_arg[0]);
1091                 tprints(", ");
1092         } else {
1093 # ifdef X32
1094                 printstat64_x32(tcp, tcp->u_arg[1]);
1095 # else
1096                 printstat64(tcp, tcp->u_arg[1]);
1097 # endif
1098         }
1099         return 0;
1100 #else
1101         return printargs(tcp);
1102 #endif
1103 }
1104
1105 int
1106 sys_newfstatat(struct tcb *tcp)
1107 {
1108         if (entering(tcp)) {
1109                 print_dirfd(tcp, tcp->u_arg[0]);
1110                 printpath(tcp, tcp->u_arg[1]);
1111                 tprints(", ");
1112         } else {
1113 #ifdef POWERPC64
1114                 if (current_personality == 0)
1115                         printstat(tcp, tcp->u_arg[2]);
1116                 else
1117                         printstat64(tcp, tcp->u_arg[2]);
1118 #elif defined HAVE_STAT64
1119                 printstat64(tcp, tcp->u_arg[2]);
1120 #else
1121                 printstat(tcp, tcp->u_arg[2]);
1122 #endif
1123                 tprints(", ");
1124                 printflags(at_flags, tcp->u_arg[3], "AT_???");
1125         }
1126         return 0;
1127 }
1128
1129 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1130 int
1131 sys_oldstat(struct tcb *tcp)
1132 {
1133         if (entering(tcp)) {
1134                 printpath(tcp, tcp->u_arg[0]);
1135                 tprints(", ");
1136         } else {
1137                 printoldstat(tcp, tcp->u_arg[1]);
1138         }
1139         return 0;
1140 }
1141 #endif
1142
1143 int
1144 sys_fstat(struct tcb *tcp)
1145 {
1146         if (entering(tcp)) {
1147                 printfd(tcp, tcp->u_arg[0]);
1148                 tprints(", ");
1149         } else {
1150                 printstat(tcp, tcp->u_arg[1]);
1151         }
1152         return 0;
1153 }
1154
1155 int
1156 sys_fstat64(struct tcb *tcp)
1157 {
1158 #ifdef HAVE_STAT64
1159         if (entering(tcp)) {
1160                 printfd(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 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1176 int
1177 sys_oldfstat(struct tcb *tcp)
1178 {
1179         if (entering(tcp)) {
1180                 printfd(tcp, tcp->u_arg[0]);
1181                 tprints(", ");
1182         } else {
1183                 printoldstat(tcp, tcp->u_arg[1]);
1184         }
1185         return 0;
1186 }
1187 #endif
1188
1189 #if defined(SPARC) || defined(SPARC64)
1190
1191 int
1192 sys_xstat(struct tcb *tcp)
1193 {
1194         if (entering(tcp)) {
1195                 tprintf("%ld, ", tcp->u_arg[0]);
1196                 printpath(tcp, tcp->u_arg[1]);
1197                 tprints(", ");
1198         } else {
1199 # ifdef _STAT64_VER
1200                 if (tcp->u_arg[0] == _STAT64_VER)
1201                         printstat64(tcp, tcp->u_arg[2]);
1202                 else
1203 # endif
1204                 printstat(tcp, tcp->u_arg[2]);
1205         }
1206         return 0;
1207 }
1208
1209 int
1210 sys_fxstat(struct tcb *tcp)
1211 {
1212         if (entering(tcp))
1213                 tprintf("%ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1]);
1214         else {
1215 # ifdef _STAT64_VER
1216                 if (tcp->u_arg[0] == _STAT64_VER)
1217                         printstat64(tcp, tcp->u_arg[2]);
1218                 else
1219 # endif
1220                 printstat(tcp, tcp->u_arg[2]);
1221         }
1222         return 0;
1223 }
1224
1225 int
1226 sys_lxstat(struct tcb *tcp)
1227 {
1228         if (entering(tcp)) {
1229                 tprintf("%ld, ", tcp->u_arg[0]);
1230                 printpath(tcp, tcp->u_arg[1]);
1231                 tprints(", ");
1232         } else {
1233 # ifdef _STAT64_VER
1234                 if (tcp->u_arg[0] == _STAT64_VER)
1235                         printstat64(tcp, tcp->u_arg[2]);
1236                 else
1237 # endif
1238                 printstat(tcp, tcp->u_arg[2]);
1239         }
1240         return 0;
1241 }
1242
1243 #endif /* SPARC[64] */