1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) 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 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 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 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 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 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 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 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 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 410 SYS_FUNC(stat64) 411 { 412 return sys_stat(tcp); 413 } 414 415 SYS_FUNC(fstat64) 416 { 417 return sys_fstat(tcp); 418 } 419 420 #endif /* HAVE_STRUCT_STAT64 */ 421 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 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 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 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 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 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 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