Home | History | Annotate | Download | only in common
      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