]> granicus.if.org Git - strace/blob - file.c
Convert do_printstat to a template function
[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 #ifdef MAJOR_IN_SYSMACROS
183 # include <sys/sysmacros.h>
184 #endif
185
186 #ifdef MAJOR_IN_MKDEV
187 # include <sys/mkdev.h>
188 #endif
189
190 /* several stats */
191
192 #if defined(SPARC) || defined(SPARC64)
193 typedef struct {
194         int     tv_sec;
195         int     tv_nsec;
196 } timestruct_t;
197
198 struct solstat {
199         unsigned        st_dev;
200         int             st_pad1[3];     /* network id */
201         unsigned        st_ino;
202         unsigned        st_mode;
203         unsigned        st_nlink;
204         unsigned        st_uid;
205         unsigned        st_gid;
206         unsigned        st_rdev;
207         int             st_pad2[2];
208         int             st_size;
209         int             st_pad3;        /* st_size, off_t expansion */
210         timestruct_t    st_atime;
211         timestruct_t    st_mtime;
212         timestruct_t    st_ctime;
213         int             st_blksize;
214         int             st_blocks;
215         char            st_fstype[16];
216         int             st_pad4[8];     /* expansion area */
217 };
218
219 static void
220 printstatsol(struct tcb *tcp, long addr)
221 {
222         struct solstat statbuf;
223
224         if (umove(tcp, addr, &statbuf) < 0) {
225                 tprints("{...}");
226                 return;
227         }
228         if (!abbrev(tcp)) {
229                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
230                         (unsigned long) ((statbuf.st_dev >> 18) & 0x3fff),
231                         (unsigned long) (statbuf.st_dev & 0x3ffff),
232                         (unsigned long) statbuf.st_ino,
233                         sprintmode(statbuf.st_mode));
234                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
235                         (unsigned long) statbuf.st_nlink,
236                         (unsigned long) statbuf.st_uid,
237                         (unsigned long) statbuf.st_gid);
238                 tprintf("st_blksize=%lu, ", (unsigned long) statbuf.st_blksize);
239                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
240         }
241         else
242                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
243         switch (statbuf.st_mode & S_IFMT) {
244         case S_IFCHR: case S_IFBLK:
245                 tprintf("st_rdev=makedev(%lu, %lu), ",
246                         (unsigned long) ((statbuf.st_rdev >> 18) & 0x3fff),
247                         (unsigned long) (statbuf.st_rdev & 0x3ffff));
248                 break;
249         default:
250                 tprintf("st_size=%u, ", statbuf.st_size);
251                 break;
252         }
253         if (!abbrev(tcp)) {
254                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime.tv_sec));
255                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime.tv_sec));
256                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime.tv_sec));
257         }
258         else
259                 tprints("...}");
260 }
261
262 # if defined(SPARC64)
263 static void
264 printstat_sparc64(struct tcb *tcp, long addr)
265 {
266         struct stat_sparc64 statbuf;
267
268         if (umove(tcp, addr, &statbuf) < 0) {
269                 tprints("{...}");
270                 return;
271         }
272
273         if (!abbrev(tcp)) {
274                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
275                         (unsigned long) major(statbuf.st_dev),
276                         (unsigned long) minor(statbuf.st_dev),
277                         (unsigned long) statbuf.st_ino,
278                         sprintmode(statbuf.st_mode));
279                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
280                         (unsigned long) statbuf.st_nlink,
281                         (unsigned long) statbuf.st_uid,
282                         (unsigned long) statbuf.st_gid);
283                 tprintf("st_blksize=%lu, ",
284                         (unsigned long) statbuf.st_blksize);
285                 tprintf("st_blocks=%lu, ",
286                         (unsigned long) statbuf.st_blocks);
287         }
288         else
289                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
290         switch (statbuf.st_mode & S_IFMT) {
291         case S_IFCHR: case S_IFBLK:
292                 tprintf("st_rdev=makedev(%lu, %lu), ",
293                         (unsigned long) major(statbuf.st_rdev),
294                         (unsigned long) minor(statbuf.st_rdev));
295                 break;
296         default:
297                 tprintf("st_size=%lu, ", statbuf.st_size);
298                 break;
299         }
300         if (!abbrev(tcp)) {
301                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
302                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
303                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
304         }
305         else
306                 tprints("...}");
307 }
308 # endif /* SPARC64 */
309 #endif /* SPARC[64] */
310
311 #if defined POWERPC64
312 struct stat_powerpc32 {
313         unsigned int    st_dev;
314         unsigned int    st_ino;
315         unsigned int    st_mode;
316         unsigned short  st_nlink;
317         unsigned int    st_uid;
318         unsigned int    st_gid;
319         unsigned int    st_rdev;
320         unsigned int    st_size;
321         unsigned int    st_blksize;
322         unsigned int    st_blocks;
323         unsigned int    st_atime;
324         unsigned int    st_atime_nsec;
325         unsigned int    st_mtime;
326         unsigned int    st_mtime_nsec;
327         unsigned int    st_ctime;
328         unsigned int    st_ctime_nsec;
329         unsigned int    __unused4;
330         unsigned int    __unused5;
331 };
332
333 static void
334 printstat_powerpc32(struct tcb *tcp, long addr)
335 {
336         struct stat_powerpc32 statbuf;
337
338         if (umove(tcp, addr, &statbuf) < 0) {
339                 tprints("{...}");
340                 return;
341         }
342
343         if (!abbrev(tcp)) {
344                 tprintf("{st_dev=makedev(%u, %u), st_ino=%u, st_mode=%s, ",
345                         major(statbuf.st_dev), minor(statbuf.st_dev),
346                         statbuf.st_ino,
347                         sprintmode(statbuf.st_mode));
348                 tprintf("st_nlink=%u, st_uid=%u, st_gid=%u, ",
349                         statbuf.st_nlink, statbuf.st_uid, statbuf.st_gid);
350                 tprintf("st_blksize=%u, ", statbuf.st_blksize);
351                 tprintf("st_blocks=%u, ", statbuf.st_blocks);
352         }
353         else
354                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
355         switch (statbuf.st_mode & S_IFMT) {
356         case S_IFCHR: case S_IFBLK:
357                 tprintf("st_rdev=makedev(%lu, %lu), ",
358                         (unsigned long) major(statbuf.st_rdev),
359                         (unsigned long) minor(statbuf.st_rdev));
360                 break;
361         default:
362                 tprintf("st_size=%u, ", statbuf.st_size);
363                 break;
364         }
365         if (!abbrev(tcp)) {
366                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
367                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
368                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
369         }
370         else
371                 tprints("...}");
372 }
373 #endif /* POWERPC64 */
374
375 #include "printstat.h"
376
377 #ifndef X32
378 static void
379 printstat(struct tcb *tcp, long addr)
380 {
381         struct stat statbuf;
382
383         if (!addr) {
384                 tprints("NULL");
385                 return;
386         }
387         if (syserror(tcp) || !verbose(tcp)) {
388                 tprintf("%#lx", addr);
389                 return;
390         }
391
392 #if defined(SPARC) || defined(SPARC64)
393         if (current_personality == 1) {
394                 printstatsol(tcp, addr);
395                 return;
396         }
397 #ifdef SPARC64
398         else if (current_personality == 2) {
399                 printstat_sparc64(tcp, addr);
400                 return;
401         }
402 #endif
403 #endif /* SPARC[64] */
404
405 #if defined POWERPC64
406         if (current_personality == 1) {
407                 printstat_powerpc32(tcp, addr);
408                 return;
409         }
410 #endif
411
412         if (umove(tcp, addr, &statbuf) < 0) {
413                 tprints("{...}");
414                 return;
415         }
416
417         do_printstat(tcp, &statbuf);
418 }
419 #else /* X32 */
420 # define printstat printstat64
421 #endif
422
423 #if !defined HAVE_STAT64 && (defined AARCH64 || defined X86_64)
424 /*
425  * Linux x86_64 has unified `struct stat' but its i386 biarch needs
426  * `struct stat64'.  Its <asm-i386/stat.h> definition expects 32-bit `long'.
427  * <linux/include/asm-x86_64/ia32.h> is not in the public includes set.
428  * __GNUC__ is needed for the required __attribute__ below.
429  *
430  * Similarly, aarch64 has a unified `struct stat' but its arm personality
431  * needs `struct stat64' (which also expects a 32-bit `long' but which
432  * shouldn't be packed).
433  */
434 struct stat64 {
435         unsigned long long      st_dev;
436         unsigned char   __pad0[4];
437         unsigned int    __st_ino;
438         unsigned int    st_mode;
439         unsigned int    st_nlink;
440         unsigned int    st_uid;
441         unsigned int    st_gid;
442         unsigned long long      st_rdev;
443         unsigned char   __pad3[4];
444         long long       st_size;
445         unsigned int    st_blksize;
446         unsigned long long      st_blocks;
447         unsigned int    st_atime;
448         unsigned int    st_atime_nsec;
449         unsigned int    st_mtime;
450         unsigned int    st_mtime_nsec;
451         unsigned int    st_ctime;
452         unsigned int    st_ctime_nsec;
453         unsigned long long      st_ino;
454 }
455 # if defined X86_64
456    __attribute__((packed))
457 #  define STAT64_SIZE   96
458 #else
459 #  define STAT64_SIZE   104
460 # endif
461 ;
462 # define HAVE_STAT64    1
463 #endif
464
465 #ifdef HAVE_STAT64
466 static void
467 printstat64(struct tcb *tcp, long addr)
468 {
469 #ifdef X32
470         struct stat statbuf;
471 #else
472         struct stat64 statbuf;
473 #endif
474
475 #ifdef STAT64_SIZE
476         (void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
477 #endif
478
479         if (!addr) {
480                 tprints("NULL");
481                 return;
482         }
483         if (syserror(tcp) || !verbose(tcp)) {
484                 tprintf("%#lx", addr);
485                 return;
486         }
487
488 #if defined(SPARC) || defined(SPARC64)
489         if (current_personality == 1) {
490                 printstatsol(tcp, addr);
491                 return;
492         }
493 # ifdef SPARC64
494         else if (current_personality == 2) {
495                 printstat_sparc64(tcp, addr);
496                 return;
497         }
498 # endif
499 #endif /* SPARC[64] */
500
501 #if defined AARCH64
502         if (current_personality != 0) {
503                 printstat(tcp, addr);
504                 return;
505         }
506 #endif
507 #if defined X86_64
508         if (current_personality != 1) {
509                 printstat(tcp, addr);
510                 return;
511         }
512 #endif
513
514         if (umove(tcp, addr, &statbuf) < 0) {
515                 tprints("{...}");
516                 return;
517         }
518
519         if (!abbrev(tcp)) {
520                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
521                         (unsigned long) major(statbuf.st_dev),
522                         (unsigned long) minor(statbuf.st_dev),
523                         (unsigned long long) statbuf.st_ino,
524                         sprintmode(statbuf.st_mode));
525                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
526                         (unsigned long) statbuf.st_nlink,
527                         (unsigned long) statbuf.st_uid,
528                         (unsigned long) statbuf.st_gid);
529 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
530                 tprintf("st_blksize=%lu, ",
531                         (unsigned long) statbuf.st_blksize);
532 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
533 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
534                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
535 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
536         }
537         else
538                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
539         switch (statbuf.st_mode & S_IFMT) {
540         case S_IFCHR: case S_IFBLK:
541 #ifdef HAVE_STRUCT_STAT_ST_RDEV
542                 tprintf("st_rdev=makedev(%lu, %lu), ",
543                         (unsigned long) major(statbuf.st_rdev),
544                         (unsigned long) minor(statbuf.st_rdev));
545 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
546                 tprintf("st_size=makedev(%lu, %lu), ",
547                         (unsigned long) major(statbuf.st_size),
548                         (unsigned long) minor(statbuf.st_size));
549 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
550                 break;
551         default:
552                 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
553                 break;
554         }
555         if (!abbrev(tcp)) {
556                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
557                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
558                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
559 #if HAVE_STRUCT_STAT_ST_FLAGS
560                 tprintf(", st_flags=%u", statbuf->st_flags);
561 #endif
562 #if HAVE_STRUCT_STAT_ST_FSTYPE
563                 tprintf(", st_fstype=%.*s",
564                         (int) sizeof statbuf.st_fstype, statbuf.st_fstype);
565 #endif
566 #if HAVE_STRUCT_STAT_ST_GEN
567                 tprintf(", st_gen=%u", statbuf.st_gen);
568 #endif
569                 tprints("}");
570         }
571         else
572                 tprints("...}");
573 }
574 #endif /* HAVE_STAT64 */
575
576 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
577 static void
578 convertoldstat(const struct __old_kernel_stat *oldbuf, struct stat *newbuf)
579 {
580         newbuf->st_dev = oldbuf->st_dev;
581         newbuf->st_ino = oldbuf->st_ino;
582         newbuf->st_mode = oldbuf->st_mode;
583         newbuf->st_nlink = oldbuf->st_nlink;
584         newbuf->st_uid = oldbuf->st_uid;
585         newbuf->st_gid = oldbuf->st_gid;
586         newbuf->st_rdev = oldbuf->st_rdev;
587         newbuf->st_size = oldbuf->st_size;
588         newbuf->st_atime = oldbuf->st_atime;
589         newbuf->st_mtime = oldbuf->st_mtime;
590         newbuf->st_ctime = oldbuf->st_ctime;
591         newbuf->st_blksize = 0; /* not supported in old_stat */
592         newbuf->st_blocks = 0; /* not supported in old_stat */
593 }
594
595 static void
596 printoldstat(struct tcb *tcp, long addr)
597 {
598         struct __old_kernel_stat statbuf;
599         struct stat newstatbuf;
600
601         if (!addr) {
602                 tprints("NULL");
603                 return;
604         }
605         if (syserror(tcp) || !verbose(tcp)) {
606                 tprintf("%#lx", addr);
607                 return;
608         }
609
610 # if defined(SPARC) || defined(SPARC64)
611         if (current_personality == 1) {
612                 printstatsol(tcp, addr);
613                 return;
614         }
615 # endif
616
617         if (umove(tcp, addr, &statbuf) < 0) {
618                 tprints("{...}");
619                 return;
620         }
621
622         convertoldstat(&statbuf, &newstatbuf);
623         do_printstat(tcp, &newstatbuf);
624 }
625 #endif
626
627 int
628 sys_stat(struct tcb *tcp)
629 {
630         if (entering(tcp)) {
631                 printpath(tcp, tcp->u_arg[0]);
632                 tprints(", ");
633         } else {
634                 printstat(tcp, tcp->u_arg[1]);
635         }
636         return 0;
637 }
638
639 #ifdef X32
640 static void
641 printstat64_x32(struct tcb *tcp, long addr)
642 {
643         struct stat64 statbuf;
644
645         if (!addr) {
646                 tprints("NULL");
647                 return;
648         }
649         if (syserror(tcp) || !verbose(tcp)) {
650                 tprintf("%#lx", addr);
651                 return;
652         }
653
654         if (umove(tcp, addr, &statbuf) < 0) {
655                 tprints("{...}");
656                 return;
657         }
658
659         if (!abbrev(tcp)) {
660                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
661                         (unsigned long) major(statbuf.st_dev),
662                         (unsigned long) minor(statbuf.st_dev),
663                         (unsigned long long) statbuf.st_ino,
664                         sprintmode(statbuf.st_mode));
665                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
666                         (unsigned long) statbuf.st_nlink,
667                         (unsigned long) statbuf.st_uid,
668                         (unsigned long) statbuf.st_gid);
669                 tprintf("st_blksize=%lu, ",
670                         (unsigned long) statbuf.st_blksize);
671                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
672         }
673         else
674                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
675         switch (statbuf.st_mode & S_IFMT) {
676         case S_IFCHR: case S_IFBLK:
677                 tprintf("st_rdev=makedev(%lu, %lu), ",
678                         (unsigned long) major(statbuf.st_rdev),
679                         (unsigned long) minor(statbuf.st_rdev));
680                 break;
681         default:
682                 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
683                 break;
684         }
685         if (!abbrev(tcp)) {
686                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
687                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
688                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
689                 tprints("}");
690         }
691         else
692                 tprints("...}");
693 }
694 #endif /* X32 */
695
696 int
697 sys_stat64(struct tcb *tcp)
698 {
699 #ifdef HAVE_STAT64
700         if (entering(tcp)) {
701                 printpath(tcp, tcp->u_arg[0]);
702                 tprints(", ");
703         } else {
704 # ifdef X32
705                 printstat64_x32(tcp, tcp->u_arg[1]);
706 # else
707                 printstat64(tcp, tcp->u_arg[1]);
708 # endif
709         }
710         return 0;
711 #else
712         return printargs(tcp);
713 #endif
714 }
715
716 int
717 sys_newfstatat(struct tcb *tcp)
718 {
719         if (entering(tcp)) {
720                 print_dirfd(tcp, tcp->u_arg[0]);
721                 printpath(tcp, tcp->u_arg[1]);
722                 tprints(", ");
723         } else {
724 #ifdef POWERPC64
725                 if (current_personality == 0)
726                         printstat(tcp, tcp->u_arg[2]);
727                 else
728                         printstat64(tcp, tcp->u_arg[2]);
729 #elif defined HAVE_STAT64
730                 printstat64(tcp, tcp->u_arg[2]);
731 #else
732                 printstat(tcp, tcp->u_arg[2]);
733 #endif
734                 tprints(", ");
735                 printflags(at_flags, tcp->u_arg[3], "AT_???");
736         }
737         return 0;
738 }
739
740 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
741 int
742 sys_oldstat(struct tcb *tcp)
743 {
744         if (entering(tcp)) {
745                 printpath(tcp, tcp->u_arg[0]);
746                 tprints(", ");
747         } else {
748                 printoldstat(tcp, tcp->u_arg[1]);
749         }
750         return 0;
751 }
752 #endif
753
754 int
755 sys_fstat(struct tcb *tcp)
756 {
757         if (entering(tcp)) {
758                 printfd(tcp, tcp->u_arg[0]);
759                 tprints(", ");
760         } else {
761                 printstat(tcp, tcp->u_arg[1]);
762         }
763         return 0;
764 }
765
766 int
767 sys_fstat64(struct tcb *tcp)
768 {
769 #ifdef HAVE_STAT64
770         if (entering(tcp)) {
771                 printfd(tcp, tcp->u_arg[0]);
772                 tprints(", ");
773         } else {
774 # ifdef X32
775                 printstat64_x32(tcp, tcp->u_arg[1]);
776 # else
777                 printstat64(tcp, tcp->u_arg[1]);
778 # endif
779         }
780         return 0;
781 #else
782         return printargs(tcp);
783 #endif
784 }
785
786 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
787 int
788 sys_oldfstat(struct tcb *tcp)
789 {
790         if (entering(tcp)) {
791                 printfd(tcp, tcp->u_arg[0]);
792                 tprints(", ");
793         } else {
794                 printoldstat(tcp, tcp->u_arg[1]);
795         }
796         return 0;
797 }
798 #endif
799
800 #if defined(SPARC) || defined(SPARC64)
801
802 int
803 sys_xstat(struct tcb *tcp)
804 {
805         if (entering(tcp)) {
806                 tprintf("%ld, ", tcp->u_arg[0]);
807                 printpath(tcp, tcp->u_arg[1]);
808                 tprints(", ");
809         } else {
810                 printstat(tcp, tcp->u_arg[2]);
811         }
812         return 0;
813 }
814
815 int
816 sys_fxstat(struct tcb *tcp)
817 {
818         if (entering(tcp)) {
819                 tprintf("%ld, ", tcp->u_arg[0]);
820                 printfd(tcp, tcp->u_arg[1]);
821                 tprints(", ");
822         } else {
823                 printstat(tcp, tcp->u_arg[2]);
824         }
825         return 0;
826 }
827
828 #endif /* SPARC || SPARC64 */