1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1997-2001 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/isa_defs.h> 30 31 #include <stdlib.h> 32 #include <unistd.h> 33 #include <string.h> 34 #include <errno.h> 35 #include <sys/types.h> 36 #include <sys/stat.h> 37 #include <sys/sysmacros.h> 38 #include "libproc.h" 39 40 #ifdef _LP64 41 /* 42 * in case of 64-bit *stat() and *stat64 library call and 32-bit subject 43 * process convert 64-bit struct stat/stat64 into 32-bit struct stat64 44 */ 45 static void 46 stat64_32_to_n(struct stat64_32 *src, struct stat *dest) 47 { 48 (void) memset(dest, 0, sizeof (*dest)); 49 dest->st_dev = DEVEXPL(src->st_dev); 50 dest->st_ino = (ino_t)src->st_ino; 51 dest->st_mode = (mode_t)src->st_mode; 52 dest->st_nlink = (nlink_t)src->st_nlink; 53 dest->st_uid = (uid_t)src->st_uid; 54 dest->st_gid = (gid_t)src->st_gid; 55 dest->st_rdev = DEVEXPL(src->st_rdev); 56 dest->st_size = (off_t)src->st_size; 57 TIMESPEC32_TO_TIMESPEC(&dest->st_atim, &src->st_atim); 58 TIMESPEC32_TO_TIMESPEC(&dest->st_mtim, &src->st_mtim); 59 TIMESPEC32_TO_TIMESPEC(&dest->st_ctim, &src->st_ctim); 60 dest->st_blksize = (blksize_t)src->st_blksize; 61 dest->st_blocks = (blkcnt_t)src->st_blocks; 62 (void) memcpy(dest->st_fstype, src->st_fstype, 63 sizeof (dest->st_fstype)); 64 } 65 #endif /* _LP64 */ 66 67 /* 68 * stat() system call -- executed by subject process 69 */ 70 int 71 pr_stat(struct ps_prochandle *Pr, const char *path, struct stat *buf) 72 { 73 sysret_t rval; /* return value from stat() */ 74 argdes_t argd[3]; /* arg descriptors for stat() */ 75 argdes_t *adp = &argd[0]; /* first argument */ 76 int syscall; /* stat, xstat or stat64 */ 77 int nargs = 2; /* number of actual arguments */ 78 int error; 79 #ifdef _LP64 80 struct stat64_32 statb64_32; 81 #endif /* _LP64 */ 82 83 if (Pr == NULL) /* no subject process */ 84 return (stat(path, buf)); 85 86 /* 87 * This is filthy, but /proc reveals everything about the 88 * system call interfaces, despite what the architects of the 89 * header files may desire. We have to know here whether we 90 * are calling stat() or xstat() in the subject. 91 */ 92 #if defined(_STAT_VER) 93 syscall = SYS_xstat; 94 nargs = 3; 95 adp->arg_value = _STAT_VER; 96 adp->arg_object = NULL; 97 adp->arg_type = AT_BYVAL; 98 adp->arg_inout = AI_INPUT; 99 adp->arg_size = 0; 100 adp++; /* move to pathname argument */ 101 #else 102 if (Pstatus(Pr)->pr_dmodel != PR_MODEL_NATIVE) { 103 /* 64-bit process controls 32-bit subject process */ 104 syscall = SYS_stat64; 105 } else { 106 syscall = SYS_stat; 107 } 108 #endif 109 110 adp->arg_value = 0; 111 adp->arg_object = (void *)path; 112 adp->arg_type = AT_BYREF; 113 adp->arg_inout = AI_INPUT; 114 adp->arg_size = strlen(path) + 1; 115 adp++; /* move to buffer argument */ 116 117 adp->arg_value = 0; 118 adp->arg_type = AT_BYREF; 119 adp->arg_inout = AI_OUTPUT; 120 #ifdef _LP64 121 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) { 122 adp->arg_object = &statb64_32; 123 adp->arg_size = sizeof (statb64_32); 124 } else { 125 adp->arg_object = buf; 126 adp->arg_size = sizeof (*buf); 127 } 128 #else /* _LP64 */ 129 adp->arg_object = buf; 130 adp->arg_size = sizeof (*buf); 131 #endif /* _LP64 */ 132 133 error = Psyscall(Pr, &rval, syscall, nargs, &argd[0]); 134 135 if (error) { 136 errno = (error > 0)? error : ENOSYS; 137 return (-1); 138 } 139 #ifdef _LP64 140 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) 141 stat64_32_to_n(&statb64_32, buf); 142 #endif /* _LP64 */ 143 return (0); 144 } 145 146 /* 147 * lstat() system call -- executed by subject process 148 */ 149 int 150 pr_lstat(struct ps_prochandle *Pr, const char *path, struct stat *buf) 151 { 152 sysret_t rval; /* return value from lstat() */ 153 argdes_t argd[3]; /* arg descriptors for lstat() */ 154 argdes_t *adp = &argd[0]; /* first argument */ 155 int syscall; /* lstat, lxstat or lstat64 */ 156 int nargs = 2; /* number of actual arguments */ 157 int error; 158 #ifdef _LP64 159 struct stat64_32 statb64_32; 160 #endif /* _LP64 */ 161 162 if (Pr == NULL) /* no subject process */ 163 return (lstat(path, buf)); 164 165 /* 166 * This is filthy, but /proc reveals everything about the 167 * system call interfaces, despite what the architects of the 168 * header files may desire. We have to know here whether we 169 * are calling lstat() or lxstat() in the subject. 170 */ 171 #if defined(_STAT_VER) 172 syscall = SYS_lxstat; 173 nargs = 3; 174 adp->arg_value = _STAT_VER; 175 adp->arg_object = NULL; 176 adp->arg_type = AT_BYVAL; 177 adp->arg_inout = AI_INPUT; 178 adp->arg_size = 0; 179 adp++; /* move to pathname argument */ 180 #else 181 if (Pstatus(Pr)->pr_dmodel != PR_MODEL_NATIVE) { 182 /* 64-bit process controls 32-bit subject process */ 183 syscall = SYS_lstat64; 184 } else { 185 syscall = SYS_lstat; 186 } 187 #endif 188 189 adp->arg_value = 0; 190 adp->arg_object = (void *)path; 191 adp->arg_type = AT_BYREF; 192 adp->arg_inout = AI_INPUT; 193 adp->arg_size = strlen(path) + 1; 194 adp++; /* move to buffer argument */ 195 196 adp->arg_value = 0; 197 adp->arg_type = AT_BYREF; 198 adp->arg_inout = AI_OUTPUT; 199 #ifdef _LP64 200 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) { 201 adp->arg_object = &statb64_32; 202 adp->arg_size = sizeof (statb64_32); 203 } else { 204 adp->arg_object = buf; 205 adp->arg_size = sizeof (*buf); 206 } 207 #else /* _LP64 */ 208 adp->arg_object = buf; 209 adp->arg_size = sizeof (*buf); 210 #endif /* _LP64 */ 211 212 error = Psyscall(Pr, &rval, syscall, nargs, &argd[0]); 213 214 if (error) { 215 errno = (error > 0)? error : ENOSYS; 216 return (-1); 217 } 218 #ifdef _LP64 219 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) 220 stat64_32_to_n(&statb64_32, buf); 221 #endif /* _LP64 */ 222 return (0); 223 } 224 225 /* 226 * fstat() system call -- executed by subject process 227 */ 228 int 229 pr_fstat(struct ps_prochandle *Pr, int fd, struct stat *buf) 230 { 231 sysret_t rval; /* return value from fstat() */ 232 argdes_t argd[3]; /* arg descriptors for fstat() */ 233 argdes_t *adp = &argd[0]; /* first argument */ 234 int syscall; /* fstat, fxstat or fstat64 */ 235 int nargs = 2; /* number of actual arguments */ 236 int error; 237 #ifdef _LP64 238 struct stat64_32 statb64_32; 239 #endif /* _LP64 */ 240 241 if (Pr == NULL) /* no subject process */ 242 return (fstat(fd, buf)); 243 244 /* 245 * This is filthy, but /proc reveals everything about the 246 * system call interfaces, despite what the architects of the 247 * header files may desire. We have to know here whether we 248 * are calling fstat() or fxstat() in the subject. 249 */ 250 #if defined(_STAT_VER) 251 syscall = SYS_fxstat; 252 nargs = 3; 253 adp->arg_value = _STAT_VER; 254 adp->arg_object = NULL; 255 adp->arg_type = AT_BYVAL; 256 adp->arg_inout = AI_INPUT; 257 adp->arg_size = 0; 258 adp++; /* move to fd argument */ 259 #else 260 if (Pstatus(Pr)->pr_dmodel != PR_MODEL_NATIVE) { 261 /* 64-bit process controls 32-bit subject process */ 262 syscall = SYS_fstat64; 263 } else { 264 syscall = SYS_fstat; 265 } 266 #endif 267 268 adp->arg_value = fd; 269 adp->arg_object = NULL; 270 adp->arg_type = AT_BYVAL; 271 adp->arg_inout = AI_INPUT; 272 adp->arg_size = 0; 273 adp++; /* move to buffer argument */ 274 275 adp->arg_value = 0; 276 adp->arg_type = AT_BYREF; 277 adp->arg_inout = AI_OUTPUT; 278 #ifdef _LP64 279 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) { 280 adp->arg_object = &statb64_32; 281 adp->arg_size = sizeof (statb64_32); 282 } else { 283 adp->arg_object = buf; 284 adp->arg_size = sizeof (*buf); 285 } 286 #else /* _LP64 */ 287 adp->arg_object = buf; 288 adp->arg_size = sizeof (*buf); 289 #endif /* _LP64 */ 290 291 error = Psyscall(Pr, &rval, syscall, nargs, &argd[0]); 292 293 if (error) { 294 errno = (error > 0)? error : ENOSYS; 295 return (-1); 296 } 297 #ifdef _LP64 298 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) 299 stat64_32_to_n(&statb64_32, buf); 300 #endif /* _LP64 */ 301 return (0); 302 } 303 304 /* 305 * stat64() system call -- executed by subject process 306 */ 307 int 308 pr_stat64(struct ps_prochandle *Pr, const char *path, struct stat64 *buf) 309 { 310 sysret_t rval; /* return value from stat64() */ 311 argdes_t argd[2]; /* arg descriptors for stat64() */ 312 argdes_t *adp = &argd[0]; /* first argument */ 313 int syscall; /* stat or stat64 */ 314 int nargs = 2; /* number of actual arguments */ 315 int error; 316 #ifdef _LP64 317 struct stat64_32 statb64_32; 318 #endif /* _LP64 */ 319 320 if (Pr == NULL) /* no subject process */ 321 return (stat64(path, buf)); 322 323 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) { 324 /* 325 * 32-bit native and 326 * 64-bit process controls 32-bit subject process 327 */ 328 syscall = SYS_stat64; 329 } else { 330 /* 64-bit native */ 331 syscall = SYS_stat; 332 } 333 334 adp->arg_value = 0; 335 adp->arg_object = (void *)path; 336 adp->arg_type = AT_BYREF; 337 adp->arg_inout = AI_INPUT; 338 adp->arg_size = strlen(path) + 1; 339 adp++; /* move to buffer argument */ 340 341 adp->arg_value = 0; 342 adp->arg_type = AT_BYREF; 343 adp->arg_inout = AI_OUTPUT; 344 #ifdef _LP64 345 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) { 346 adp->arg_object = &statb64_32; 347 adp->arg_size = sizeof (statb64_32); 348 } else { 349 adp->arg_object = buf; 350 adp->arg_size = sizeof (*buf); 351 } 352 #else /* _LP64 */ 353 adp->arg_object = buf; 354 adp->arg_size = sizeof (*buf); 355 #endif /* _LP64 */ 356 357 error = Psyscall(Pr, &rval, syscall, nargs, &argd[0]); 358 359 if (error) { 360 errno = (error > 0)? error : ENOSYS; 361 return (-1); 362 } 363 #ifdef _LP64 364 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) 365 stat64_32_to_n(&statb64_32, (struct stat *)buf); 366 #endif /* _LP64 */ 367 return (0); 368 } 369 370 /* 371 * lstat64() system call -- executed by subject process 372 */ 373 int 374 pr_lstat64(struct ps_prochandle *Pr, const char *path, struct stat64 *buf) 375 { 376 sysret_t rval; /* return value from lstat64() */ 377 argdes_t argd[2]; /* arg descriptors for lstat64() */ 378 argdes_t *adp = &argd[0]; /* first argument */ 379 int syscall; /* lstat or lstat64 */ 380 int nargs = 2; /* number of actual arguments */ 381 int error; 382 #ifdef _LP64 383 struct stat64_32 statb64_32; 384 #endif /* _LP64 */ 385 386 if (Pr == NULL) /* no subject process */ 387 return (lstat64(path, buf)); 388 389 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) { 390 /* 391 * 32-bit native and 392 * 64-bit process controls 32-bit subject process 393 */ 394 syscall = SYS_lstat64; 395 } else { 396 /* 64-bit native */ 397 syscall = SYS_lstat; 398 } 399 400 adp->arg_value = 0; 401 adp->arg_object = (void *)path; 402 adp->arg_type = AT_BYREF; 403 adp->arg_inout = AI_INPUT; 404 adp->arg_size = strlen(path) + 1; 405 adp++; /* move to buffer argument */ 406 407 adp->arg_value = 0; 408 adp->arg_type = AT_BYREF; 409 adp->arg_inout = AI_OUTPUT; 410 #ifdef _LP64 411 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) { 412 adp->arg_object = &statb64_32; 413 adp->arg_size = sizeof (statb64_32); 414 } else { 415 adp->arg_object = buf; 416 adp->arg_size = sizeof (*buf); 417 } 418 #else /* _LP64 */ 419 adp->arg_object = buf; 420 adp->arg_size = sizeof (*buf); 421 #endif /* _LP64 */ 422 423 error = Psyscall(Pr, &rval, syscall, nargs, &argd[0]); 424 425 if (error) { 426 errno = (error > 0)? error : ENOSYS; 427 return (-1); 428 } 429 #ifdef _LP64 430 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) 431 stat64_32_to_n(&statb64_32, (struct stat *)buf); 432 #endif /* _LP64 */ 433 return (0); 434 } 435 436 /* 437 * fstat64() system call -- executed by subject process 438 */ 439 int 440 pr_fstat64(struct ps_prochandle *Pr, int fd, struct stat64 *buf) 441 { 442 sysret_t rval; /* return value from fstat64() */ 443 argdes_t argd[2]; /* arg descriptors for fstat64() */ 444 argdes_t *adp = &argd[0]; /* first argument */ 445 int syscall; /* fstat or fstat64 */ 446 int nargs = 2; /* number of actual arguments */ 447 int error; 448 #ifdef _LP64 449 struct stat64_32 statb64_32; 450 #endif /* _LP64 */ 451 452 if (Pr == NULL) /* no subject process */ 453 return (fstat64(fd, buf)); 454 455 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) { 456 /* 457 * 32-bit native and 458 * 64-bit process controls 32-bit subject process 459 */ 460 syscall = SYS_fstat64; 461 } else { 462 /* 64-bit native */ 463 syscall = SYS_fstat; 464 } 465 466 adp->arg_value = fd; 467 adp->arg_object = NULL; 468 adp->arg_type = AT_BYVAL; 469 adp->arg_inout = AI_INPUT; 470 adp->arg_size = 0; 471 adp++; /* move to buffer argument */ 472 473 adp->arg_value = 0; 474 adp->arg_type = AT_BYREF; 475 adp->arg_inout = AI_OUTPUT; 476 #ifdef _LP64 477 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) { 478 adp->arg_object = &statb64_32; 479 adp->arg_size = sizeof (statb64_32); 480 } else { 481 adp->arg_object = buf; 482 adp->arg_size = sizeof (*buf); 483 } 484 #else /* _LP64 */ 485 adp->arg_object = buf; 486 adp->arg_size = sizeof (*buf); 487 #endif /* _LP64 */ 488 489 error = Psyscall(Pr, &rval, syscall, nargs, &argd[0]); 490 491 if (error) { 492 errno = (error > 0)? error : ENOSYS; 493 return (-1); 494 } 495 #ifdef _LP64 496 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) 497 stat64_32_to_n(&statb64_32, (struct stat *)buf); 498 #endif /* _LP64 */ 499 return (0); 500 } 501