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