]> granicus.if.org Git - strace/blob - file.c
sparc: fix fxstat decoding
[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 "xlat/fileflags.h"
376
377 static void
378 realprintstat(struct tcb *tcp, struct stat *statbuf)
379 {
380         if (!abbrev(tcp)) {
381                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
382                         (unsigned long) major(statbuf->st_dev),
383                         (unsigned long) minor(statbuf->st_dev),
384                         (unsigned long) statbuf->st_ino,
385                         sprintmode(statbuf->st_mode));
386                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
387                         (unsigned long) statbuf->st_nlink,
388                         (unsigned long) statbuf->st_uid,
389                         (unsigned long) statbuf->st_gid);
390 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
391                 tprintf("st_blksize=%lu, ", (unsigned long) statbuf->st_blksize);
392 #endif
393 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
394                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf->st_blocks);
395 #endif
396         }
397         else
398                 tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode));
399         switch (statbuf->st_mode & S_IFMT) {
400         case S_IFCHR: case S_IFBLK:
401 #ifdef HAVE_STRUCT_STAT_ST_RDEV
402                 tprintf("st_rdev=makedev(%lu, %lu), ",
403                         (unsigned long) major(statbuf->st_rdev),
404                         (unsigned long) minor(statbuf->st_rdev));
405 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
406                 tprintf("st_size=makedev(%lu, %lu), ",
407                         (unsigned long) major(statbuf->st_size),
408                         (unsigned long) minor(statbuf->st_size));
409 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
410                 break;
411         default:
412                 tprintf("st_size=%lu, ", (unsigned long) statbuf->st_size);
413                 break;
414         }
415         if (!abbrev(tcp)) {
416                 tprintf("st_atime=%s, ", sprinttime(statbuf->st_atime));
417                 tprintf("st_mtime=%s, ", sprinttime(statbuf->st_mtime));
418                 tprintf("st_ctime=%s", sprinttime(statbuf->st_ctime));
419 #if HAVE_STRUCT_STAT_ST_FLAGS
420                 tprints(", st_flags=");
421                 printflags(fileflags, statbuf->st_flags, "UF_???");
422 #endif
423 #if HAVE_STRUCT_STAT_ST_ACLCNT
424                 tprintf(", st_aclcnt=%d", statbuf->st_aclcnt);
425 #endif
426 #if HAVE_STRUCT_STAT_ST_LEVEL
427                 tprintf(", st_level=%ld", statbuf->st_level);
428 #endif
429 #if HAVE_STRUCT_STAT_ST_FSTYPE
430                 tprintf(", st_fstype=%.*s",
431                         (int) sizeof statbuf->st_fstype, statbuf->st_fstype);
432 #endif
433 #if HAVE_STRUCT_STAT_ST_GEN
434                 tprintf(", st_gen=%u", statbuf->st_gen);
435 #endif
436                 tprints("}");
437         }
438         else
439                 tprints("...}");
440 }
441
442 #ifndef X32
443 static void
444 printstat(struct tcb *tcp, long addr)
445 {
446         struct stat statbuf;
447
448         if (!addr) {
449                 tprints("NULL");
450                 return;
451         }
452         if (syserror(tcp) || !verbose(tcp)) {
453                 tprintf("%#lx", addr);
454                 return;
455         }
456
457 #if defined(SPARC) || defined(SPARC64)
458         if (current_personality == 1) {
459                 printstatsol(tcp, addr);
460                 return;
461         }
462 #ifdef SPARC64
463         else if (current_personality == 2) {
464                 printstat_sparc64(tcp, addr);
465                 return;
466         }
467 #endif
468 #endif /* SPARC[64] */
469
470 #if defined POWERPC64
471         if (current_personality == 1) {
472                 printstat_powerpc32(tcp, addr);
473                 return;
474         }
475 #endif
476
477         if (umove(tcp, addr, &statbuf) < 0) {
478                 tprints("{...}");
479                 return;
480         }
481
482         realprintstat(tcp, &statbuf);
483 }
484 #else /* X32 */
485 # define printstat printstat64
486 #endif
487
488 #if !defined HAVE_STAT64 && (defined AARCH64 || defined X86_64)
489 /*
490  * Linux x86_64 has unified `struct stat' but its i386 biarch needs
491  * `struct stat64'.  Its <asm-i386/stat.h> definition expects 32-bit `long'.
492  * <linux/include/asm-x86_64/ia32.h> is not in the public includes set.
493  * __GNUC__ is needed for the required __attribute__ below.
494  *
495  * Similarly, aarch64 has a unified `struct stat' but its arm personality
496  * needs `struct stat64' (which also expects a 32-bit `long' but which
497  * shouldn't be packed).
498  */
499 struct stat64 {
500         unsigned long long      st_dev;
501         unsigned char   __pad0[4];
502         unsigned int    __st_ino;
503         unsigned int    st_mode;
504         unsigned int    st_nlink;
505         unsigned int    st_uid;
506         unsigned int    st_gid;
507         unsigned long long      st_rdev;
508         unsigned char   __pad3[4];
509         long long       st_size;
510         unsigned int    st_blksize;
511         unsigned long long      st_blocks;
512         unsigned int    st_atime;
513         unsigned int    st_atime_nsec;
514         unsigned int    st_mtime;
515         unsigned int    st_mtime_nsec;
516         unsigned int    st_ctime;
517         unsigned int    st_ctime_nsec;
518         unsigned long long      st_ino;
519 }
520 # if defined X86_64
521    __attribute__((packed))
522 #  define STAT64_SIZE   96
523 #else
524 #  define STAT64_SIZE   104
525 # endif
526 ;
527 # define HAVE_STAT64    1
528 #endif
529
530 #ifdef HAVE_STAT64
531 static void
532 printstat64(struct tcb *tcp, long addr)
533 {
534 #ifdef X32
535         struct stat statbuf;
536 #else
537         struct stat64 statbuf;
538 #endif
539
540 #ifdef STAT64_SIZE
541         (void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
542 #endif
543
544         if (!addr) {
545                 tprints("NULL");
546                 return;
547         }
548         if (syserror(tcp) || !verbose(tcp)) {
549                 tprintf("%#lx", addr);
550                 return;
551         }
552
553 #if defined(SPARC) || defined(SPARC64)
554         if (current_personality == 1) {
555                 printstatsol(tcp, addr);
556                 return;
557         }
558 # ifdef SPARC64
559         else if (current_personality == 2) {
560                 printstat_sparc64(tcp, addr);
561                 return;
562         }
563 # endif
564 #endif /* SPARC[64] */
565
566 #if defined AARCH64
567         if (current_personality != 0) {
568                 printstat(tcp, addr);
569                 return;
570         }
571 #endif
572 #if defined X86_64
573         if (current_personality != 1) {
574                 printstat(tcp, addr);
575                 return;
576         }
577 #endif
578
579         if (umove(tcp, addr, &statbuf) < 0) {
580                 tprints("{...}");
581                 return;
582         }
583
584         if (!abbrev(tcp)) {
585                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
586                         (unsigned long) major(statbuf.st_dev),
587                         (unsigned long) minor(statbuf.st_dev),
588                         (unsigned long long) statbuf.st_ino,
589                         sprintmode(statbuf.st_mode));
590                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
591                         (unsigned long) statbuf.st_nlink,
592                         (unsigned long) statbuf.st_uid,
593                         (unsigned long) statbuf.st_gid);
594 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
595                 tprintf("st_blksize=%lu, ",
596                         (unsigned long) statbuf.st_blksize);
597 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
598 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
599                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
600 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
601         }
602         else
603                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
604         switch (statbuf.st_mode & S_IFMT) {
605         case S_IFCHR: case S_IFBLK:
606 #ifdef HAVE_STRUCT_STAT_ST_RDEV
607                 tprintf("st_rdev=makedev(%lu, %lu), ",
608                         (unsigned long) major(statbuf.st_rdev),
609                         (unsigned long) minor(statbuf.st_rdev));
610 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
611                 tprintf("st_size=makedev(%lu, %lu), ",
612                         (unsigned long) major(statbuf.st_size),
613                         (unsigned long) minor(statbuf.st_size));
614 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
615                 break;
616         default:
617                 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
618                 break;
619         }
620         if (!abbrev(tcp)) {
621                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
622                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
623                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
624 #if HAVE_STRUCT_STAT_ST_FLAGS
625                 tprints(", st_flags=");
626                 printflags(fileflags, statbuf.st_flags, "UF_???");
627 #endif
628 #if HAVE_STRUCT_STAT_ST_ACLCNT
629                 tprintf(", st_aclcnt=%d", statbuf.st_aclcnt);
630 #endif
631 #if HAVE_STRUCT_STAT_ST_LEVEL
632                 tprintf(", st_level=%ld", statbuf.st_level);
633 #endif
634 #if HAVE_STRUCT_STAT_ST_FSTYPE
635                 tprintf(", st_fstype=%.*s",
636                         (int) sizeof statbuf.st_fstype, statbuf.st_fstype);
637 #endif
638 #if HAVE_STRUCT_STAT_ST_GEN
639                 tprintf(", st_gen=%u", statbuf.st_gen);
640 #endif
641                 tprints("}");
642         }
643         else
644                 tprints("...}");
645 }
646 #endif /* HAVE_STAT64 */
647
648 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
649 static void
650 convertoldstat(const struct __old_kernel_stat *oldbuf, struct stat *newbuf)
651 {
652         newbuf->st_dev = oldbuf->st_dev;
653         newbuf->st_ino = oldbuf->st_ino;
654         newbuf->st_mode = oldbuf->st_mode;
655         newbuf->st_nlink = oldbuf->st_nlink;
656         newbuf->st_uid = oldbuf->st_uid;
657         newbuf->st_gid = oldbuf->st_gid;
658         newbuf->st_rdev = oldbuf->st_rdev;
659         newbuf->st_size = oldbuf->st_size;
660         newbuf->st_atime = oldbuf->st_atime;
661         newbuf->st_mtime = oldbuf->st_mtime;
662         newbuf->st_ctime = oldbuf->st_ctime;
663         newbuf->st_blksize = 0; /* not supported in old_stat */
664         newbuf->st_blocks = 0; /* not supported in old_stat */
665 }
666
667 static void
668 printoldstat(struct tcb *tcp, long addr)
669 {
670         struct __old_kernel_stat statbuf;
671         struct stat newstatbuf;
672
673         if (!addr) {
674                 tprints("NULL");
675                 return;
676         }
677         if (syserror(tcp) || !verbose(tcp)) {
678                 tprintf("%#lx", addr);
679                 return;
680         }
681
682 # if defined(SPARC) || defined(SPARC64)
683         if (current_personality == 1) {
684                 printstatsol(tcp, addr);
685                 return;
686         }
687 # endif
688
689         if (umove(tcp, addr, &statbuf) < 0) {
690                 tprints("{...}");
691                 return;
692         }
693
694         convertoldstat(&statbuf, &newstatbuf);
695         realprintstat(tcp, &newstatbuf);
696 }
697 #endif
698
699 int
700 sys_stat(struct tcb *tcp)
701 {
702         if (entering(tcp)) {
703                 printpath(tcp, tcp->u_arg[0]);
704                 tprints(", ");
705         } else {
706                 printstat(tcp, tcp->u_arg[1]);
707         }
708         return 0;
709 }
710
711 #ifdef X32
712 static void
713 printstat64_x32(struct tcb *tcp, long addr)
714 {
715         struct stat64 statbuf;
716
717         if (!addr) {
718                 tprints("NULL");
719                 return;
720         }
721         if (syserror(tcp) || !verbose(tcp)) {
722                 tprintf("%#lx", addr);
723                 return;
724         }
725
726         if (umove(tcp, addr, &statbuf) < 0) {
727                 tprints("{...}");
728                 return;
729         }
730
731         if (!abbrev(tcp)) {
732                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
733                         (unsigned long) major(statbuf.st_dev),
734                         (unsigned long) minor(statbuf.st_dev),
735                         (unsigned long long) statbuf.st_ino,
736                         sprintmode(statbuf.st_mode));
737                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
738                         (unsigned long) statbuf.st_nlink,
739                         (unsigned long) statbuf.st_uid,
740                         (unsigned long) statbuf.st_gid);
741                 tprintf("st_blksize=%lu, ",
742                         (unsigned long) statbuf.st_blksize);
743                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
744         }
745         else
746                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
747         switch (statbuf.st_mode & S_IFMT) {
748         case S_IFCHR: case S_IFBLK:
749                 tprintf("st_rdev=makedev(%lu, %lu), ",
750                         (unsigned long) major(statbuf.st_rdev),
751                         (unsigned long) minor(statbuf.st_rdev));
752                 break;
753         default:
754                 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
755                 break;
756         }
757         if (!abbrev(tcp)) {
758                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
759                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
760                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
761                 tprints("}");
762         }
763         else
764                 tprints("...}");
765 }
766 #endif /* X32 */
767
768 int
769 sys_stat64(struct tcb *tcp)
770 {
771 #ifdef HAVE_STAT64
772         if (entering(tcp)) {
773                 printpath(tcp, tcp->u_arg[0]);
774                 tprints(", ");
775         } else {
776 # ifdef X32
777                 printstat64_x32(tcp, tcp->u_arg[1]);
778 # else
779                 printstat64(tcp, tcp->u_arg[1]);
780 # endif
781         }
782         return 0;
783 #else
784         return printargs(tcp);
785 #endif
786 }
787
788 int
789 sys_newfstatat(struct tcb *tcp)
790 {
791         if (entering(tcp)) {
792                 print_dirfd(tcp, tcp->u_arg[0]);
793                 printpath(tcp, tcp->u_arg[1]);
794                 tprints(", ");
795         } else {
796 #ifdef POWERPC64
797                 if (current_personality == 0)
798                         printstat(tcp, tcp->u_arg[2]);
799                 else
800                         printstat64(tcp, tcp->u_arg[2]);
801 #elif defined HAVE_STAT64
802                 printstat64(tcp, tcp->u_arg[2]);
803 #else
804                 printstat(tcp, tcp->u_arg[2]);
805 #endif
806                 tprints(", ");
807                 printflags(at_flags, tcp->u_arg[3], "AT_???");
808         }
809         return 0;
810 }
811
812 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
813 int
814 sys_oldstat(struct tcb *tcp)
815 {
816         if (entering(tcp)) {
817                 printpath(tcp, tcp->u_arg[0]);
818                 tprints(", ");
819         } else {
820                 printoldstat(tcp, tcp->u_arg[1]);
821         }
822         return 0;
823 }
824 #endif
825
826 int
827 sys_fstat(struct tcb *tcp)
828 {
829         if (entering(tcp)) {
830                 printfd(tcp, tcp->u_arg[0]);
831                 tprints(", ");
832         } else {
833                 printstat(tcp, tcp->u_arg[1]);
834         }
835         return 0;
836 }
837
838 int
839 sys_fstat64(struct tcb *tcp)
840 {
841 #ifdef HAVE_STAT64
842         if (entering(tcp)) {
843                 printfd(tcp, tcp->u_arg[0]);
844                 tprints(", ");
845         } else {
846 # ifdef X32
847                 printstat64_x32(tcp, tcp->u_arg[1]);
848 # else
849                 printstat64(tcp, tcp->u_arg[1]);
850 # endif
851         }
852         return 0;
853 #else
854         return printargs(tcp);
855 #endif
856 }
857
858 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
859 int
860 sys_oldfstat(struct tcb *tcp)
861 {
862         if (entering(tcp)) {
863                 printfd(tcp, tcp->u_arg[0]);
864                 tprints(", ");
865         } else {
866                 printoldstat(tcp, tcp->u_arg[1]);
867         }
868         return 0;
869 }
870 #endif
871
872 #if defined(SPARC) || defined(SPARC64)
873
874 int
875 sys_xstat(struct tcb *tcp)
876 {
877         if (entering(tcp)) {
878                 tprintf("%ld, ", tcp->u_arg[0]);
879                 printpath(tcp, tcp->u_arg[1]);
880                 tprints(", ");
881         } else {
882                 printstat(tcp, tcp->u_arg[2]);
883         }
884         return 0;
885 }
886
887 int
888 sys_fxstat(struct tcb *tcp)
889 {
890         if (entering(tcp)) {
891                 tprintf("%ld, ", tcp->u_arg[0]);
892                 printfd(tcp, tcp->u_arg[1]);
893                 tprints(", ");
894         } else {
895                 printstat(tcp, tcp->u_arg[2]);
896         }
897         return 0;
898 }
899
900 #endif /* SPARC || SPARC64 */