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 #undef dev_t
34 #undef ino_t
35 #undef mode_t
36 #undef nlink_t
37 #undef uid_t
38 #undef gid_t
39 #undef off_t
40 #undef loff_t
41 #define dev_t __kernel_dev_t
42 #define ino_t __kernel_ino_t
43 #define mode_t __kernel_mode_t
44 #define nlink_t __kernel_nlink_t
45 #define uid_t __kernel_uid_t
46 #define gid_t __kernel_gid_t
47 #define off_t __kernel_off_t
48 #define loff_t __kernel_loff_t
49
50 #include <asm/stat.h>
51
52 #undef dev_t
53 #undef ino_t
54 #undef mode_t
55 #undef nlink_t
56 #undef uid_t
57 #undef gid_t
58 #undef off_t
59 #undef loff_t
60 #define dev_t dev_t
61 #define ino_t ino_t
62 #define mode_t mode_t
63 #define nlink_t nlink_t
64 #define uid_t uid_t
65 #define gid_t gid_t
66 #define off_t off_t
67 #define loff_t loff_t
68
69 /* for S_IFMT */
70 #define stat libc_stat
71 #define stat64 libc_stat64
72 #include <sys/stat.h>
73 #undef stat
74 #undef stat64
75 /* These might be macros. */
76 #undef st_atime
77 #undef st_mtime
78 #undef st_ctime
79
80 #if defined MAJOR_IN_SYSMACROS
81 # include <sys/sysmacros.h>
82 #elif defined MAJOR_IN_MKDEV
83 # include <sys/mkdev.h>
84 #endif
85
86 /* several stats */
87
88 #include "printstat.h"
89
90 #undef STAT32_PERSONALITY
91 #if SUPPORTED_PERSONALITIES > 1
92 # if defined AARCH64 || defined X86_64 || defined X32
93 struct stat32 {
94 unsigned int st_dev;
95 unsigned int st_ino;
96 unsigned short st_mode;
97 unsigned short st_nlink;
98 unsigned short st_uid;
99 unsigned short st_gid;
100 unsigned int st_rdev;
101 unsigned int st_size;
102 unsigned int st_blksize;
103 unsigned int st_blocks;
104 unsigned int st_atime;
105 unsigned int st_atime_nsec;
106 unsigned int st_mtime;
107 unsigned int st_mtime_nsec;
108 unsigned int st_ctime;
109 unsigned int st_ctime_nsec;
110 unsigned int __unused4;
111 unsigned int __unused5;
112 };
113 # ifdef AARCH64
114 # define STAT32_PERSONALITY 0
115 # else
116 # define STAT32_PERSONALITY 1
117 # endif
118 # elif defined POWERPC64
119 struct stat32 {
120 unsigned int st_dev;
121 unsigned int st_ino;
122 unsigned int st_mode;
123 unsigned short st_nlink;
124 unsigned int st_uid;
125 unsigned int st_gid;
126 unsigned int st_rdev;
127 unsigned int st_size;
128 unsigned int st_blksize;
129 unsigned int st_blocks;
130 unsigned int st_atime;
131 unsigned int st_atime_nsec;
132 unsigned int st_mtime;
133 unsigned int st_mtime_nsec;
134 unsigned int st_ctime;
135 unsigned int st_ctime_nsec;
136 unsigned int __unused4;
137 unsigned int __unused5;
138 };
139 # define STAT32_PERSONALITY 1
140 # elif defined SPARC64
141 struct stat32 {
142 unsigned short st_dev;
143 unsigned int st_ino;
144 unsigned short st_mode;
145 unsigned short st_nlink;
146 unsigned short st_uid;
147 unsigned short st_gid;
148 unsigned short st_rdev;
149 unsigned int st_size;
150 unsigned int st_atime;
151 unsigned int st_atime_nsec;
152 unsigned int st_mtime;
153 unsigned int st_mtime_nsec;
154 unsigned int st_ctime;
155 unsigned int st_ctime_nsec;
156 unsigned int st_blksize;
157 unsigned int st_blocks;
158 unsigned int __unused4[2];
159 };
160 # define STAT32_PERSONALITY 0
161 # elif defined SPARC
162 # /* no 64-bit personalities */
163 # elif defined TILE
164 # /* no 32-bit stat */
165 # else
166 # warning FIXME: check whether struct stat32 definition is needed for this architecture!
167 # endif /* X86_64 || X32 || POWERPC64 */
168 #endif /* SUPPORTED_PERSONALITIES > 1 */
169
170 #ifdef STAT32_PERSONALITY
171 # define DO_PRINTSTAT do_printstat32
172 # define STRUCT_STAT struct stat32
173 # undef HAVE_STRUCT_STAT_ST_FLAGS
174 # undef HAVE_STRUCT_STAT_ST_FSTYPE
175 # undef HAVE_STRUCT_STAT_ST_GEN
176 # include "printstat.h"
177
178 static void
printstat32(struct tcb * tcp,long addr)179 printstat32(struct tcb *tcp, long addr)
180 {
181 struct stat32 statbuf;
182
183 if (umove(tcp, addr, &statbuf) < 0) {
184 tprints("{...}");
185 return;
186 }
187
188 do_printstat32(tcp, &statbuf);
189 }
190 #endif /* STAT32_PERSONALITY */
191
192 #if defined(SPARC) || defined(SPARC64)
193
194 struct solstat {
195 unsigned st_dev;
196 unsigned int st_pad1[3]; /* network id */
197 unsigned st_ino;
198 unsigned st_mode;
199 unsigned st_nlink;
200 unsigned st_uid;
201 unsigned st_gid;
202 unsigned st_rdev;
203 unsigned int st_pad2[2];
204 unsigned int st_size;
205 unsigned int st_pad3; /* st_size, off_t expansion */
206 unsigned int st_atime;
207 unsigned int st_atime_nsec;
208 unsigned int st_mtime;
209 unsigned int st_mtime_nsec;
210 unsigned int st_ctime;
211 unsigned int st_ctime_nsec;
212 unsigned int st_blksize;
213 unsigned int st_blocks;
214 char st_fstype[16];
215 unsigned int st_pad4[8]; /* expansion area */
216 };
217
218 # define DO_PRINTSTAT do_printstat_sol
219 # define STRUCT_STAT struct solstat
220 # define STAT_MAJOR(x) (((x) >> 18) & 0x3fff)
221 # define STAT_MINOR(x) ((x) & 0x3ffff)
222 # undef HAVE_STRUCT_STAT_ST_FLAGS
223 # undef HAVE_STRUCT_STAT_ST_FSTYPE
224 # undef HAVE_STRUCT_STAT_ST_GEN
225 # include "printstat.h"
226
227 static void
printstatsol(struct tcb * tcp,long addr)228 printstatsol(struct tcb *tcp, long addr)
229 {
230 struct solstat statbuf;
231
232 if (umove(tcp, addr, &statbuf) < 0) {
233 tprints("{...}");
234 return;
235 }
236
237 do_printstat_sol(tcp, &statbuf);
238 }
239
240 #endif /* SPARC || SPARC64 */
241
242 static void
printstat(struct tcb * tcp,long addr)243 printstat(struct tcb *tcp, long addr)
244 {
245 struct stat statbuf;
246
247 if (!addr) {
248 tprints("NULL");
249 return;
250 }
251 if (syserror(tcp) || !verbose(tcp)) {
252 tprintf("%#lx", addr);
253 return;
254 }
255
256 #ifdef STAT32_PERSONALITY
257 if (current_personality == STAT32_PERSONALITY) {
258 printstat32(tcp, addr);
259 return;
260 }
261 #endif
262
263 #if defined(SPARC) || defined(SPARC64)
264 if (current_personality == 1) {
265 printstatsol(tcp, addr);
266 return;
267 }
268 #endif /* SPARC || SPARC64 */
269
270 if (umove(tcp, addr, &statbuf) < 0) {
271 tprints("{...}");
272 return;
273 }
274
275 do_printstat(tcp, &statbuf);
276 }
277
SYS_FUNC(stat)278 SYS_FUNC(stat)
279 {
280 if (entering(tcp)) {
281 printpath(tcp, tcp->u_arg[0]);
282 tprints(", ");
283 } else {
284 printstat(tcp, tcp->u_arg[1]);
285 }
286 return 0;
287 }
288
SYS_FUNC(fstat)289 SYS_FUNC(fstat)
290 {
291 if (entering(tcp)) {
292 printfd(tcp, tcp->u_arg[0]);
293 tprints(", ");
294 } else {
295 printstat(tcp, tcp->u_arg[1]);
296 }
297 return 0;
298 }
299
300 #if defined STAT32_PERSONALITY && !defined HAVE_STRUCT_STAT64
301 # if defined AARCH64 || defined X86_64 || defined X32
302 /*
303 * Linux x86_64 and x32 have unified `struct stat' but their i386 personality
304 * needs `struct stat64'.
305 * linux/arch/x86/include/uapi/asm/stat.h defines `struct stat64' only for i386.
306 *
307 * Similarly, aarch64 has a unified `struct stat' but its arm personality
308 * needs `struct stat64' (unlike x86, it shouldn't be packed).
309 */
310 struct stat64 {
311 unsigned long long st_dev;
312 unsigned char __pad0[4];
313 unsigned int __st_ino;
314 unsigned int st_mode;
315 unsigned int st_nlink;
316 unsigned int st_uid;
317 unsigned int st_gid;
318 unsigned long long st_rdev;
319 unsigned char __pad3[4];
320 long long st_size;
321 unsigned int st_blksize;
322 unsigned long long 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 long long st_ino;
330 }
331 # if defined X86_64 || defined X32
332 ATTRIBUTE_PACKED
333 # define STAT64_SIZE 96
334 # else
335 # define STAT64_SIZE 104
336 # endif
337 ;
338 # define HAVE_STRUCT_STAT64 1
339 # else /* !(AARCH64 || X86_64 || X32) */
340 # warning FIXME: check whether struct stat64 definition is needed for this architecture!
341 # endif
342 #endif /* STAT32_PERSONALITY && !HAVE_STRUCT_STAT64 */
343
344 #ifdef HAVE_STRUCT_STAT64
345
346 # define DO_PRINTSTAT do_printstat64
347 # define STRUCT_STAT struct stat64
348 # undef HAVE_STRUCT_STAT_ST_FLAGS
349 # undef HAVE_STRUCT_STAT_ST_FSTYPE
350 # undef HAVE_STRUCT_STAT_ST_GEN
351 # include "printstat.h"
352
353 static void
printstat64(struct tcb * tcp,long addr)354 printstat64(struct tcb *tcp, long addr)
355 {
356 struct stat64 statbuf;
357
358 # ifdef STAT64_SIZE
359 (void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
360 # endif
361
362 if (!addr) {
363 tprints("NULL");
364 return;
365 }
366 if (syserror(tcp) || !verbose(tcp)) {
367 tprintf("%#lx", addr);
368 return;
369 }
370
371 # ifdef STAT32_PERSONALITY
372 if (current_personality != STAT32_PERSONALITY) {
373 printstat(tcp, addr);
374 return;
375 }
376 # endif /* STAT32_PERSONALITY */
377
378 if (umove(tcp, addr, &statbuf) < 0) {
379 tprints("{...}");
380 return;
381 }
382
383 do_printstat64(tcp, &statbuf);
384 }
385
SYS_FUNC(stat64)386 SYS_FUNC(stat64)
387 {
388 if (entering(tcp)) {
389 printpath(tcp, tcp->u_arg[0]);
390 tprints(", ");
391 } else {
392 printstat64(tcp, tcp->u_arg[1]);
393 }
394 return 0;
395 }
396
SYS_FUNC(fstat64)397 SYS_FUNC(fstat64)
398 {
399 if (entering(tcp)) {
400 printfd(tcp, tcp->u_arg[0]);
401 tprints(", ");
402 } else {
403 printstat64(tcp, tcp->u_arg[1]);
404 }
405 return 0;
406 }
407
408 #else
409
SYS_FUNC(stat64)410 SYS_FUNC(stat64)
411 {
412 return sys_stat(tcp);
413 }
414
SYS_FUNC(fstat64)415 SYS_FUNC(fstat64)
416 {
417 return sys_fstat(tcp);
418 }
419
420 #endif /* HAVE_STRUCT_STAT64 */
421
SYS_FUNC(newfstatat)422 SYS_FUNC(newfstatat)
423 {
424 if (entering(tcp)) {
425 print_dirfd(tcp, tcp->u_arg[0]);
426 printpath(tcp, tcp->u_arg[1]);
427 tprints(", ");
428 } else {
429 #if defined STAT32_PERSONALITY
430 if (current_personality == STAT32_PERSONALITY)
431 printstat64(tcp, tcp->u_arg[2]);
432 else
433 printstat(tcp, tcp->u_arg[2]);
434 #elif defined HAVE_STRUCT_STAT64
435 printstat64(tcp, tcp->u_arg[2]);
436 #else
437 printstat(tcp, tcp->u_arg[2]);
438 #endif /* STAT32_PERSONALITY || HAVE_STRUCT_STAT64 */
439 tprints(", ");
440 printflags(at_flags, tcp->u_arg[3], "AT_???");
441 }
442 return 0;
443 }
444
445 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
446
447 static void
convertoldstat(const struct __old_kernel_stat * oldbuf,struct stat * newbuf)448 convertoldstat(const struct __old_kernel_stat *oldbuf, struct stat *newbuf)
449 {
450 memset(newbuf, 0, sizeof(*newbuf));
451 newbuf->st_dev = oldbuf->st_dev;
452 newbuf->st_ino = oldbuf->st_ino;
453 newbuf->st_mode = oldbuf->st_mode;
454 newbuf->st_nlink = oldbuf->st_nlink;
455 newbuf->st_uid = oldbuf->st_uid;
456 newbuf->st_gid = oldbuf->st_gid;
457 newbuf->st_rdev = oldbuf->st_rdev;
458 newbuf->st_size = oldbuf->st_size;
459 newbuf->st_atime = oldbuf->st_atime;
460 newbuf->st_mtime = oldbuf->st_mtime;
461 newbuf->st_ctime = oldbuf->st_ctime;
462 }
463
464 static void
printoldstat(struct tcb * tcp,long addr)465 printoldstat(struct tcb *tcp, long addr)
466 {
467 struct __old_kernel_stat statbuf;
468 struct stat newstatbuf;
469
470 if (!addr) {
471 tprints("NULL");
472 return;
473 }
474 if (syserror(tcp) || !verbose(tcp)) {
475 tprintf("%#lx", addr);
476 return;
477 }
478
479 # if defined(SPARC) || defined(SPARC64)
480 if (current_personality == 1) {
481 printstatsol(tcp, addr);
482 return;
483 }
484 # endif
485
486 if (umove(tcp, addr, &statbuf) < 0) {
487 tprints("{...}");
488 return;
489 }
490
491 convertoldstat(&statbuf, &newstatbuf);
492 do_printstat(tcp, &newstatbuf);
493 }
494
SYS_FUNC(oldstat)495 SYS_FUNC(oldstat)
496 {
497 if (entering(tcp)) {
498 printpath(tcp, tcp->u_arg[0]);
499 tprints(", ");
500 } else {
501 printoldstat(tcp, tcp->u_arg[1]);
502 }
503 return 0;
504 }
505
SYS_FUNC(oldfstat)506 SYS_FUNC(oldfstat)
507 {
508 if (entering(tcp)) {
509 printfd(tcp, tcp->u_arg[0]);
510 tprints(", ");
511 } else {
512 printoldstat(tcp, tcp->u_arg[1]);
513 }
514 return 0;
515 }
516
517 #endif /* HAVE_STRUCT___OLD_KERNEL_STAT */
518
519 #if defined(SPARC) || defined(SPARC64)
520
SYS_FUNC(xstat)521 SYS_FUNC(xstat)
522 {
523 if (entering(tcp)) {
524 tprintf("%ld, ", tcp->u_arg[0]);
525 printpath(tcp, tcp->u_arg[1]);
526 tprints(", ");
527 } else {
528 printstat(tcp, tcp->u_arg[2]);
529 }
530 return 0;
531 }
532
SYS_FUNC(fxstat)533 SYS_FUNC(fxstat)
534 {
535 if (entering(tcp)) {
536 tprintf("%ld, ", tcp->u_arg[0]);
537 printfd(tcp, tcp->u_arg[1]);
538 tprints(", ");
539 } else {
540 printstat(tcp, tcp->u_arg[2]);
541 }
542 return 0;
543 }
544
545 #endif /* SPARC || SPARC64 */
546