]> granicus.if.org Git - strace/blob - file.c
file.c: move readahead 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 /* several stats */
456
457 #if defined(SPARC) || defined(SPARC64)
458 typedef struct {
459         int     tv_sec;
460         int     tv_nsec;
461 } timestruct_t;
462
463 struct solstat {
464         unsigned        st_dev;
465         int             st_pad1[3];     /* network id */
466         unsigned        st_ino;
467         unsigned        st_mode;
468         unsigned        st_nlink;
469         unsigned        st_uid;
470         unsigned        st_gid;
471         unsigned        st_rdev;
472         int             st_pad2[2];
473         int             st_size;
474         int             st_pad3;        /* st_size, off_t expansion */
475         timestruct_t    st_atime;
476         timestruct_t    st_mtime;
477         timestruct_t    st_ctime;
478         int             st_blksize;
479         int             st_blocks;
480         char            st_fstype[16];
481         int             st_pad4[8];     /* expansion area */
482 };
483
484 static void
485 printstatsol(struct tcb *tcp, long addr)
486 {
487         struct solstat statbuf;
488
489         if (umove(tcp, addr, &statbuf) < 0) {
490                 tprints("{...}");
491                 return;
492         }
493         if (!abbrev(tcp)) {
494                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
495                         (unsigned long) ((statbuf.st_dev >> 18) & 0x3fff),
496                         (unsigned long) (statbuf.st_dev & 0x3ffff),
497                         (unsigned long) statbuf.st_ino,
498                         sprintmode(statbuf.st_mode));
499                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
500                         (unsigned long) statbuf.st_nlink,
501                         (unsigned long) statbuf.st_uid,
502                         (unsigned long) statbuf.st_gid);
503                 tprintf("st_blksize=%lu, ", (unsigned long) statbuf.st_blksize);
504                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
505         }
506         else
507                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
508         switch (statbuf.st_mode & S_IFMT) {
509         case S_IFCHR: case S_IFBLK:
510                 tprintf("st_rdev=makedev(%lu, %lu), ",
511                         (unsigned long) ((statbuf.st_rdev >> 18) & 0x3fff),
512                         (unsigned long) (statbuf.st_rdev & 0x3ffff));
513                 break;
514         default:
515                 tprintf("st_size=%u, ", statbuf.st_size);
516                 break;
517         }
518         if (!abbrev(tcp)) {
519                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime.tv_sec));
520                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime.tv_sec));
521                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime.tv_sec));
522         }
523         else
524                 tprints("...}");
525 }
526
527 # if defined(SPARC64)
528 static void
529 printstat_sparc64(struct tcb *tcp, long addr)
530 {
531         struct stat_sparc64 statbuf;
532
533         if (umove(tcp, addr, &statbuf) < 0) {
534                 tprints("{...}");
535                 return;
536         }
537
538         if (!abbrev(tcp)) {
539                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
540                         (unsigned long) major(statbuf.st_dev),
541                         (unsigned long) minor(statbuf.st_dev),
542                         (unsigned long) statbuf.st_ino,
543                         sprintmode(statbuf.st_mode));
544                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
545                         (unsigned long) statbuf.st_nlink,
546                         (unsigned long) statbuf.st_uid,
547                         (unsigned long) statbuf.st_gid);
548                 tprintf("st_blksize=%lu, ",
549                         (unsigned long) statbuf.st_blksize);
550                 tprintf("st_blocks=%lu, ",
551                         (unsigned long) statbuf.st_blocks);
552         }
553         else
554                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
555         switch (statbuf.st_mode & S_IFMT) {
556         case S_IFCHR: case S_IFBLK:
557                 tprintf("st_rdev=makedev(%lu, %lu), ",
558                         (unsigned long) major(statbuf.st_rdev),
559                         (unsigned long) minor(statbuf.st_rdev));
560                 break;
561         default:
562                 tprintf("st_size=%lu, ", statbuf.st_size);
563                 break;
564         }
565         if (!abbrev(tcp)) {
566                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
567                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
568                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
569         }
570         else
571                 tprints("...}");
572 }
573 # endif /* SPARC64 */
574 #endif /* SPARC[64] */
575
576 #if defined POWERPC64
577 struct stat_powerpc32 {
578         unsigned int    st_dev;
579         unsigned int    st_ino;
580         unsigned int    st_mode;
581         unsigned short  st_nlink;
582         unsigned int    st_uid;
583         unsigned int    st_gid;
584         unsigned int    st_rdev;
585         unsigned int    st_size;
586         unsigned int    st_blksize;
587         unsigned int    st_blocks;
588         unsigned int    st_atime;
589         unsigned int    st_atime_nsec;
590         unsigned int    st_mtime;
591         unsigned int    st_mtime_nsec;
592         unsigned int    st_ctime;
593         unsigned int    st_ctime_nsec;
594         unsigned int    __unused4;
595         unsigned int    __unused5;
596 };
597
598 static void
599 printstat_powerpc32(struct tcb *tcp, long addr)
600 {
601         struct stat_powerpc32 statbuf;
602
603         if (umove(tcp, addr, &statbuf) < 0) {
604                 tprints("{...}");
605                 return;
606         }
607
608         if (!abbrev(tcp)) {
609                 tprintf("{st_dev=makedev(%u, %u), st_ino=%u, st_mode=%s, ",
610                         major(statbuf.st_dev), minor(statbuf.st_dev),
611                         statbuf.st_ino,
612                         sprintmode(statbuf.st_mode));
613                 tprintf("st_nlink=%u, st_uid=%u, st_gid=%u, ",
614                         statbuf.st_nlink, statbuf.st_uid, statbuf.st_gid);
615                 tprintf("st_blksize=%u, ", statbuf.st_blksize);
616                 tprintf("st_blocks=%u, ", statbuf.st_blocks);
617         }
618         else
619                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
620         switch (statbuf.st_mode & S_IFMT) {
621         case S_IFCHR: case S_IFBLK:
622                 tprintf("st_rdev=makedev(%lu, %lu), ",
623                         (unsigned long) major(statbuf.st_rdev),
624                         (unsigned long) minor(statbuf.st_rdev));
625                 break;
626         default:
627                 tprintf("st_size=%u, ", statbuf.st_size);
628                 break;
629         }
630         if (!abbrev(tcp)) {
631                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
632                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
633                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
634         }
635         else
636                 tprints("...}");
637 }
638 #endif /* POWERPC64 */
639
640 #include "xlat/fileflags.h"
641
642 static void
643 realprintstat(struct tcb *tcp, struct stat *statbuf)
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 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
656                 tprintf("st_blksize=%lu, ", (unsigned long) statbuf->st_blksize);
657 #endif
658 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
659                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf->st_blocks);
660 #endif
661         }
662         else
663                 tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode));
664         switch (statbuf->st_mode & S_IFMT) {
665         case S_IFCHR: case S_IFBLK:
666 #ifdef HAVE_STRUCT_STAT_ST_RDEV
667                 tprintf("st_rdev=makedev(%lu, %lu), ",
668                         (unsigned long) major(statbuf->st_rdev),
669                         (unsigned long) minor(statbuf->st_rdev));
670 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
671                 tprintf("st_size=makedev(%lu, %lu), ",
672                         (unsigned long) major(statbuf->st_size),
673                         (unsigned long) minor(statbuf->st_size));
674 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
675                 break;
676         default:
677                 tprintf("st_size=%lu, ", (unsigned long) statbuf->st_size);
678                 break;
679         }
680         if (!abbrev(tcp)) {
681                 tprintf("st_atime=%s, ", sprinttime(statbuf->st_atime));
682                 tprintf("st_mtime=%s, ", sprinttime(statbuf->st_mtime));
683                 tprintf("st_ctime=%s", sprinttime(statbuf->st_ctime));
684 #if HAVE_STRUCT_STAT_ST_FLAGS
685                 tprints(", st_flags=");
686                 printflags(fileflags, statbuf->st_flags, "UF_???");
687 #endif
688 #if HAVE_STRUCT_STAT_ST_ACLCNT
689                 tprintf(", st_aclcnt=%d", statbuf->st_aclcnt);
690 #endif
691 #if HAVE_STRUCT_STAT_ST_LEVEL
692                 tprintf(", st_level=%ld", statbuf->st_level);
693 #endif
694 #if HAVE_STRUCT_STAT_ST_FSTYPE
695                 tprintf(", st_fstype=%.*s",
696                         (int) sizeof statbuf->st_fstype, statbuf->st_fstype);
697 #endif
698 #if HAVE_STRUCT_STAT_ST_GEN
699                 tprintf(", st_gen=%u", statbuf->st_gen);
700 #endif
701                 tprints("}");
702         }
703         else
704                 tprints("...}");
705 }
706
707 #ifndef X32
708 static void
709 printstat(struct tcb *tcp, long addr)
710 {
711         struct stat statbuf;
712
713         if (!addr) {
714                 tprints("NULL");
715                 return;
716         }
717         if (syserror(tcp) || !verbose(tcp)) {
718                 tprintf("%#lx", addr);
719                 return;
720         }
721
722 #if defined(SPARC) || defined(SPARC64)
723         if (current_personality == 1) {
724                 printstatsol(tcp, addr);
725                 return;
726         }
727 #ifdef SPARC64
728         else if (current_personality == 2) {
729                 printstat_sparc64(tcp, addr);
730                 return;
731         }
732 #endif
733 #endif /* SPARC[64] */
734
735 #if defined POWERPC64
736         if (current_personality == 1) {
737                 printstat_powerpc32(tcp, addr);
738                 return;
739         }
740 #endif
741
742         if (umove(tcp, addr, &statbuf) < 0) {
743                 tprints("{...}");
744                 return;
745         }
746
747         realprintstat(tcp, &statbuf);
748 }
749 #else /* X32 */
750 # define printstat printstat64
751 #endif
752
753 #if !defined HAVE_STAT64 && (defined AARCH64 || defined X86_64)
754 /*
755  * Linux x86_64 has unified `struct stat' but its i386 biarch needs
756  * `struct stat64'.  Its <asm-i386/stat.h> definition expects 32-bit `long'.
757  * <linux/include/asm-x86_64/ia32.h> is not in the public includes set.
758  * __GNUC__ is needed for the required __attribute__ below.
759  *
760  * Similarly, aarch64 has a unified `struct stat' but its arm personality
761  * needs `struct stat64' (which also expects a 32-bit `long' but which
762  * shouldn't be packed).
763  */
764 struct stat64 {
765         unsigned long long      st_dev;
766         unsigned char   __pad0[4];
767         unsigned int    __st_ino;
768         unsigned int    st_mode;
769         unsigned int    st_nlink;
770         unsigned int    st_uid;
771         unsigned int    st_gid;
772         unsigned long long      st_rdev;
773         unsigned char   __pad3[4];
774         long long       st_size;
775         unsigned int    st_blksize;
776         unsigned long long      st_blocks;
777         unsigned int    st_atime;
778         unsigned int    st_atime_nsec;
779         unsigned int    st_mtime;
780         unsigned int    st_mtime_nsec;
781         unsigned int    st_ctime;
782         unsigned int    st_ctime_nsec;
783         unsigned long long      st_ino;
784 }
785 # if defined X86_64
786    __attribute__((packed))
787 #  define STAT64_SIZE   96
788 #else
789 #  define STAT64_SIZE   104
790 # endif
791 ;
792 # define HAVE_STAT64    1
793 #endif
794
795 #ifdef HAVE_STAT64
796 static void
797 printstat64(struct tcb *tcp, long addr)
798 {
799 #ifdef X32
800         struct stat statbuf;
801 #else
802         struct stat64 statbuf;
803 #endif
804
805 #ifdef STAT64_SIZE
806         (void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
807 #endif
808
809         if (!addr) {
810                 tprints("NULL");
811                 return;
812         }
813         if (syserror(tcp) || !verbose(tcp)) {
814                 tprintf("%#lx", addr);
815                 return;
816         }
817
818 #if defined(SPARC) || defined(SPARC64)
819         if (current_personality == 1) {
820                 printstatsol(tcp, addr);
821                 return;
822         }
823 # ifdef SPARC64
824         else if (current_personality == 2) {
825                 printstat_sparc64(tcp, addr);
826                 return;
827         }
828 # endif
829 #endif /* SPARC[64] */
830
831 #if defined AARCH64
832         if (current_personality != 0) {
833                 printstat(tcp, addr);
834                 return;
835         }
836 #endif
837 #if defined X86_64
838         if (current_personality != 1) {
839                 printstat(tcp, addr);
840                 return;
841         }
842 #endif
843
844         if (umove(tcp, addr, &statbuf) < 0) {
845                 tprints("{...}");
846                 return;
847         }
848
849         if (!abbrev(tcp)) {
850                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
851                         (unsigned long) major(statbuf.st_dev),
852                         (unsigned long) minor(statbuf.st_dev),
853                         (unsigned long long) statbuf.st_ino,
854                         sprintmode(statbuf.st_mode));
855                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
856                         (unsigned long) statbuf.st_nlink,
857                         (unsigned long) statbuf.st_uid,
858                         (unsigned long) statbuf.st_gid);
859 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
860                 tprintf("st_blksize=%lu, ",
861                         (unsigned long) statbuf.st_blksize);
862 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
863 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
864                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
865 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
866         }
867         else
868                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
869         switch (statbuf.st_mode & S_IFMT) {
870         case S_IFCHR: case S_IFBLK:
871 #ifdef HAVE_STRUCT_STAT_ST_RDEV
872                 tprintf("st_rdev=makedev(%lu, %lu), ",
873                         (unsigned long) major(statbuf.st_rdev),
874                         (unsigned long) minor(statbuf.st_rdev));
875 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
876                 tprintf("st_size=makedev(%lu, %lu), ",
877                         (unsigned long) major(statbuf.st_size),
878                         (unsigned long) minor(statbuf.st_size));
879 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
880                 break;
881         default:
882                 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
883                 break;
884         }
885         if (!abbrev(tcp)) {
886                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
887                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
888                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
889 #if HAVE_STRUCT_STAT_ST_FLAGS
890                 tprints(", st_flags=");
891                 printflags(fileflags, statbuf.st_flags, "UF_???");
892 #endif
893 #if HAVE_STRUCT_STAT_ST_ACLCNT
894                 tprintf(", st_aclcnt=%d", statbuf.st_aclcnt);
895 #endif
896 #if HAVE_STRUCT_STAT_ST_LEVEL
897                 tprintf(", st_level=%ld", statbuf.st_level);
898 #endif
899 #if HAVE_STRUCT_STAT_ST_FSTYPE
900                 tprintf(", st_fstype=%.*s",
901                         (int) sizeof statbuf.st_fstype, statbuf.st_fstype);
902 #endif
903 #if HAVE_STRUCT_STAT_ST_GEN
904                 tprintf(", st_gen=%u", statbuf.st_gen);
905 #endif
906                 tprints("}");
907         }
908         else
909                 tprints("...}");
910 }
911 #endif /* HAVE_STAT64 */
912
913 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
914 static void
915 convertoldstat(const struct __old_kernel_stat *oldbuf, struct stat *newbuf)
916 {
917         newbuf->st_dev = oldbuf->st_dev;
918         newbuf->st_ino = oldbuf->st_ino;
919         newbuf->st_mode = oldbuf->st_mode;
920         newbuf->st_nlink = oldbuf->st_nlink;
921         newbuf->st_uid = oldbuf->st_uid;
922         newbuf->st_gid = oldbuf->st_gid;
923         newbuf->st_rdev = oldbuf->st_rdev;
924         newbuf->st_size = oldbuf->st_size;
925         newbuf->st_atime = oldbuf->st_atime;
926         newbuf->st_mtime = oldbuf->st_mtime;
927         newbuf->st_ctime = oldbuf->st_ctime;
928         newbuf->st_blksize = 0; /* not supported in old_stat */
929         newbuf->st_blocks = 0; /* not supported in old_stat */
930 }
931
932 static void
933 printoldstat(struct tcb *tcp, long addr)
934 {
935         struct __old_kernel_stat statbuf;
936         struct stat newstatbuf;
937
938         if (!addr) {
939                 tprints("NULL");
940                 return;
941         }
942         if (syserror(tcp) || !verbose(tcp)) {
943                 tprintf("%#lx", addr);
944                 return;
945         }
946
947 # if defined(SPARC) || defined(SPARC64)
948         if (current_personality == 1) {
949                 printstatsol(tcp, addr);
950                 return;
951         }
952 # endif
953
954         if (umove(tcp, addr, &statbuf) < 0) {
955                 tprints("{...}");
956                 return;
957         }
958
959         convertoldstat(&statbuf, &newstatbuf);
960         realprintstat(tcp, &newstatbuf);
961 }
962 #endif
963
964 int
965 sys_stat(struct tcb *tcp)
966 {
967         if (entering(tcp)) {
968                 printpath(tcp, tcp->u_arg[0]);
969                 tprints(", ");
970         } else {
971                 printstat(tcp, tcp->u_arg[1]);
972         }
973         return 0;
974 }
975
976 #ifdef X32
977 static void
978 printstat64_x32(struct tcb *tcp, long addr)
979 {
980         struct stat64 statbuf;
981
982         if (!addr) {
983                 tprints("NULL");
984                 return;
985         }
986         if (syserror(tcp) || !verbose(tcp)) {
987                 tprintf("%#lx", addr);
988                 return;
989         }
990
991         if (umove(tcp, addr, &statbuf) < 0) {
992                 tprints("{...}");
993                 return;
994         }
995
996         if (!abbrev(tcp)) {
997                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
998                         (unsigned long) major(statbuf.st_dev),
999                         (unsigned long) minor(statbuf.st_dev),
1000                         (unsigned long long) statbuf.st_ino,
1001                         sprintmode(statbuf.st_mode));
1002                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
1003                         (unsigned long) statbuf.st_nlink,
1004                         (unsigned long) statbuf.st_uid,
1005                         (unsigned long) statbuf.st_gid);
1006                 tprintf("st_blksize=%lu, ",
1007                         (unsigned long) statbuf.st_blksize);
1008                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
1009         }
1010         else
1011                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
1012         switch (statbuf.st_mode & S_IFMT) {
1013         case S_IFCHR: case S_IFBLK:
1014                 tprintf("st_rdev=makedev(%lu, %lu), ",
1015                         (unsigned long) major(statbuf.st_rdev),
1016                         (unsigned long) minor(statbuf.st_rdev));
1017                 break;
1018         default:
1019                 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
1020                 break;
1021         }
1022         if (!abbrev(tcp)) {
1023                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
1024                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
1025                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
1026                 tprints("}");
1027         }
1028         else
1029                 tprints("...}");
1030 }
1031 #endif /* X32 */
1032
1033 int
1034 sys_stat64(struct tcb *tcp)
1035 {
1036 #ifdef HAVE_STAT64
1037         if (entering(tcp)) {
1038                 printpath(tcp, tcp->u_arg[0]);
1039                 tprints(", ");
1040         } else {
1041 # ifdef X32
1042                 printstat64_x32(tcp, tcp->u_arg[1]);
1043 # else
1044                 printstat64(tcp, tcp->u_arg[1]);
1045 # endif
1046         }
1047         return 0;
1048 #else
1049         return printargs(tcp);
1050 #endif
1051 }
1052
1053 int
1054 sys_newfstatat(struct tcb *tcp)
1055 {
1056         if (entering(tcp)) {
1057                 print_dirfd(tcp, tcp->u_arg[0]);
1058                 printpath(tcp, tcp->u_arg[1]);
1059                 tprints(", ");
1060         } else {
1061 #ifdef POWERPC64
1062                 if (current_personality == 0)
1063                         printstat(tcp, tcp->u_arg[2]);
1064                 else
1065                         printstat64(tcp, tcp->u_arg[2]);
1066 #elif defined HAVE_STAT64
1067                 printstat64(tcp, tcp->u_arg[2]);
1068 #else
1069                 printstat(tcp, tcp->u_arg[2]);
1070 #endif
1071                 tprints(", ");
1072                 printflags(at_flags, tcp->u_arg[3], "AT_???");
1073         }
1074         return 0;
1075 }
1076
1077 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1078 int
1079 sys_oldstat(struct tcb *tcp)
1080 {
1081         if (entering(tcp)) {
1082                 printpath(tcp, tcp->u_arg[0]);
1083                 tprints(", ");
1084         } else {
1085                 printoldstat(tcp, tcp->u_arg[1]);
1086         }
1087         return 0;
1088 }
1089 #endif
1090
1091 int
1092 sys_fstat(struct tcb *tcp)
1093 {
1094         if (entering(tcp)) {
1095                 printfd(tcp, tcp->u_arg[0]);
1096                 tprints(", ");
1097         } else {
1098                 printstat(tcp, tcp->u_arg[1]);
1099         }
1100         return 0;
1101 }
1102
1103 int
1104 sys_fstat64(struct tcb *tcp)
1105 {
1106 #ifdef HAVE_STAT64
1107         if (entering(tcp)) {
1108                 printfd(tcp, tcp->u_arg[0]);
1109                 tprints(", ");
1110         } else {
1111 # ifdef X32
1112                 printstat64_x32(tcp, tcp->u_arg[1]);
1113 # else
1114                 printstat64(tcp, tcp->u_arg[1]);
1115 # endif
1116         }
1117         return 0;
1118 #else
1119         return printargs(tcp);
1120 #endif
1121 }
1122
1123 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1124 int
1125 sys_oldfstat(struct tcb *tcp)
1126 {
1127         if (entering(tcp)) {
1128                 printfd(tcp, tcp->u_arg[0]);
1129                 tprints(", ");
1130         } else {
1131                 printoldstat(tcp, tcp->u_arg[1]);
1132         }
1133         return 0;
1134 }
1135 #endif
1136
1137 #if defined(SPARC) || defined(SPARC64)
1138
1139 int
1140 sys_xstat(struct tcb *tcp)
1141 {
1142         if (entering(tcp)) {
1143                 tprintf("%ld, ", tcp->u_arg[0]);
1144                 printpath(tcp, tcp->u_arg[1]);
1145                 tprints(", ");
1146         } else {
1147 # ifdef _STAT64_VER
1148                 if (tcp->u_arg[0] == _STAT64_VER)
1149                         printstat64(tcp, tcp->u_arg[2]);
1150                 else
1151 # endif
1152                 printstat(tcp, tcp->u_arg[2]);
1153         }
1154         return 0;
1155 }
1156
1157 int
1158 sys_fxstat(struct tcb *tcp)
1159 {
1160         if (entering(tcp))
1161                 tprintf("%ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1]);
1162         else {
1163 # ifdef _STAT64_VER
1164                 if (tcp->u_arg[0] == _STAT64_VER)
1165                         printstat64(tcp, tcp->u_arg[2]);
1166                 else
1167 # endif
1168                 printstat(tcp, tcp->u_arg[2]);
1169         }
1170         return 0;
1171 }
1172
1173 int
1174 sys_lxstat(struct tcb *tcp)
1175 {
1176         if (entering(tcp)) {
1177                 tprintf("%ld, ", tcp->u_arg[0]);
1178                 printpath(tcp, tcp->u_arg[1]);
1179                 tprints(", ");
1180         } else {
1181 # ifdef _STAT64_VER
1182                 if (tcp->u_arg[0] == _STAT64_VER)
1183                         printstat64(tcp, tcp->u_arg[2]);
1184                 else
1185 # endif
1186                 printstat(tcp, tcp->u_arg[2]);
1187         }
1188         return 0;
1189 }
1190
1191 #endif /* SPARC[64] */