1#include "defs.h" 2 3#include "xlat/whence_codes.h" 4 5/* Linux kernel has exactly one version of lseek: 6 * fs/read_write.c::SYSCALL_DEFINE3(lseek, unsigned, fd, off_t, offset, unsigned, origin) 7 * In kernel, off_t is always the same as (kernel's) long 8 * (see include/uapi/asm-generic/posix_types.h), 9 * which means that on x32 we need to use tcp->ext_arg[N] to get offset argument. 10 * Use test/x32_lseek.c to test lseek decoding. 11 */ 12#if defined(LINUX_MIPSN32) || defined(X32) 13SYS_FUNC(lseek) 14{ 15 long long offset; 16 int whence; 17 18 if (entering(tcp)) { 19 printfd(tcp, tcp->u_arg[0]); 20 offset = tcp->ext_arg[1]; 21 whence = tcp->u_arg[2]; 22 if (whence == SEEK_SET) 23 tprintf(", %llu, ", offset); 24 else 25 tprintf(", %lld, ", offset); 26 printxval(whence_codes, whence, "SEEK_???"); 27 } 28 return RVAL_LUDECIMAL; 29} 30#else 31SYS_FUNC(lseek) 32{ 33 long offset; 34 int whence; 35 36 if (entering(tcp)) { 37 printfd(tcp, tcp->u_arg[0]); 38 offset = tcp->u_arg[1]; 39 whence = tcp->u_arg[2]; 40 if (whence == SEEK_SET) 41 tprintf(", %lu, ", offset); 42 else 43 tprintf(", %ld, ", offset); 44 printxval(whence_codes, whence, "SEEK_???"); 45 } 46 return RVAL_UDECIMAL; 47} 48#endif 49 50/* llseek syscall takes explicitly two ulong arguments hi, lo, 51 * rather than one 64-bit argument for which LONG_LONG works 52 * appropriate for the native byte order. 53 * 54 * See kernel's fs/read_write.c::SYSCALL_DEFINE5(llseek, ...) 55 * 56 * hi,lo are "unsigned longs" and combined exactly this way in kernel: 57 * ((loff_t) hi << 32) | lo 58 * Note that for architectures with kernel's long wider than userspace long 59 * (such as x32), combining code will use *kernel's*, i.e. *wide* longs 60 * for hi and lo. We would need to use tcp->ext_arg[N] on x32... 61 * ...however, x32 (and x86_64) does not _have_ llseek syscall as such. 62 */ 63SYS_FUNC(llseek) 64{ 65 if (entering(tcp)) { 66 printfd(tcp, tcp->u_arg[0]); 67 if (tcp->u_arg[4] == SEEK_SET) 68 tprintf(", %llu, ", 69 ((long long) tcp->u_arg[1]) << 32 | 70 (unsigned long long) (unsigned) tcp->u_arg[2]); 71 else 72 tprintf(", %lld, ", 73 ((long long) tcp->u_arg[1]) << 32 | 74 (unsigned long long) (unsigned) tcp->u_arg[2]); 75 } 76 else { 77 long long off; 78 if (syserror(tcp) || umove(tcp, tcp->u_arg[3], &off) < 0) 79 tprintf("%#lx, ", tcp->u_arg[3]); 80 else 81 tprintf("[%llu], ", off); 82 printxval(whence_codes, tcp->u_arg[4], "SEEK_???"); 83 } 84 return 0; 85} 86