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) 1998-2000 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdlib.h> 30 #include <unistd.h> 31 #include <errno.h> 32 #include "libproc.h" 33 34 typedef union { 35 offset_t full; /* full 64 bit offset value */ 36 uint32_t half[2]; /* two 32-bit halves */ 37 } offsets_t; 38 39 /* 40 * lseek() system call -- executed by subject process. 41 */ 42 off_t 43 pr_lseek(struct ps_prochandle *Pr, int filedes, off_t offset, int whence) 44 { 45 int syscall; /* SYS_lseek or SYS_llseek */ 46 int nargs; /* 3 or 4, depending on syscall */ 47 offsets_t off; 48 sysret_t rval; /* return value from lseek() */ 49 argdes_t argd[4]; /* arg descriptors for lseek() */ 50 argdes_t *adp; 51 int error; 52 53 if (Pr == NULL) 54 return (lseek(filedes, offset, whence)); 55 56 adp = &argd[0]; /* filedes argument */ 57 adp->arg_value = filedes; 58 adp->arg_object = NULL; 59 adp->arg_type = AT_BYVAL; 60 adp->arg_inout = AI_INPUT; 61 adp->arg_size = 0; 62 63 adp++; /* offset argument */ 64 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_NATIVE) { 65 syscall = SYS_lseek; 66 nargs = 3; 67 adp->arg_value = offset; 68 adp->arg_object = NULL; 69 adp->arg_type = AT_BYVAL; 70 adp->arg_inout = AI_INPUT; 71 adp->arg_size = 0; 72 } else { 73 syscall = SYS_llseek; 74 nargs = 4; 75 off.full = offset; 76 adp->arg_value = off.half[0]; /* first 32 bits */ 77 adp->arg_object = NULL; 78 adp->arg_type = AT_BYVAL; 79 adp->arg_inout = AI_INPUT; 80 adp->arg_size = 0; 81 adp++; 82 adp->arg_value = off.half[1]; /* second 32 bits */ 83 adp->arg_object = NULL; 84 adp->arg_type = AT_BYVAL; 85 adp->arg_inout = AI_INPUT; 86 adp->arg_size = 0; 87 } 88 89 adp++; /* whence argument */ 90 adp->arg_value = whence; 91 adp->arg_object = NULL; 92 adp->arg_type = AT_BYVAL; 93 adp->arg_inout = AI_INPUT; 94 adp->arg_size = 0; 95 96 error = Psyscall(Pr, &rval, syscall, nargs, &argd[0]); 97 98 if (error) { 99 errno = (error > 0)? error : ENOSYS; 100 return ((off_t)(-1)); 101 } 102 103 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_NATIVE) 104 offset = rval.sys_rval1; 105 else { 106 off.half[0] = (uint32_t)rval.sys_rval1; 107 off.half[1] = (uint32_t)rval.sys_rval2; 108 offset = (off_t)off.full; 109 } 110 111 return (offset); 112 } 113 114 /* 115 * llseek() system call -- executed by subject process. 116 */ 117 offset_t 118 pr_llseek(struct ps_prochandle *Pr, int filedes, offset_t offset, int whence) 119 { 120 int syscall; /* SYS_lseek or SYS_llseek */ 121 int nargs; /* 3 or 4, depending on syscall */ 122 offsets_t off; 123 sysret_t rval; /* return value from llseek() */ 124 argdes_t argd[4]; /* arg descriptors for llseek() */ 125 argdes_t *adp; 126 int error; 127 128 if (Pr == NULL) 129 return (llseek(filedes, offset, whence)); 130 131 adp = &argd[0]; /* filedes argument */ 132 adp->arg_value = filedes; 133 adp->arg_object = NULL; 134 adp->arg_type = AT_BYVAL; 135 adp->arg_inout = AI_INPUT; 136 adp->arg_size = 0; 137 138 adp++; /* offset argument */ 139 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_LP64) { 140 syscall = SYS_lseek; 141 nargs = 3; 142 adp->arg_value = offset; 143 adp->arg_object = NULL; 144 adp->arg_type = AT_BYVAL; 145 adp->arg_inout = AI_INPUT; 146 adp->arg_size = 0; 147 } else { 148 syscall = SYS_llseek; 149 nargs = 4; 150 off.full = offset; 151 adp->arg_value = off.half[0]; /* first 32 bits */ 152 adp->arg_object = NULL; 153 adp->arg_type = AT_BYVAL; 154 adp->arg_inout = AI_INPUT; 155 adp->arg_size = 0; 156 adp++; 157 adp->arg_value = off.half[1]; /* second 32 bits */ 158 adp->arg_object = NULL; 159 adp->arg_type = AT_BYVAL; 160 adp->arg_inout = AI_INPUT; 161 adp->arg_size = 0; 162 } 163 164 adp++; /* whence argument */ 165 adp->arg_value = whence; 166 adp->arg_object = NULL; 167 adp->arg_type = AT_BYVAL; 168 adp->arg_inout = AI_INPUT; 169 adp->arg_size = 0; 170 171 error = Psyscall(Pr, &rval, syscall, nargs, &argd[0]); 172 173 if (error) { 174 errno = (error > 0)? error : ENOSYS; 175 return ((offset_t)(-1)); 176 } 177 178 if (Pstatus(Pr)->pr_dmodel == PR_MODEL_LP64) 179 offset = rval.sys_rval1; 180 else { 181 off.half[0] = (uint32_t)rval.sys_rval1; 182 off.half[1] = (uint32_t)rval.sys_rval2; 183 offset = off.full; 184 } 185 186 return (offset); 187 } 188