From: Tom Hughes Date: Tue, 5 Jul 2005 23:25:17 +0000 (+0000) Subject: Sort out the mess that is pread64/pwrite64 properly. All three platforms X-Git-Tag: svn/VALGRIND_3_0_0~208 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fcf186b9c83ec08fc9e871173492886f73f86ee3;p=thirdparty%2Fvalgrind.git Sort out the mess that is pread64/pwrite64 properly. All three platforms that we currently support use the same handlers in the kernel without any platform specific wrappers. The final argument is a 64 bit argument however, which means that it requires two registers on x86 and ppc32 and only one on amd64. The reason it works in the kernel is that x86 and ppc32 calling conventions inside the kernel work out correctly and the values get joined together. For our purposes we make x86 and ppc32 use the generic veneer with five arguments and amd64 use a platform specific one with four... git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4110 --- diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index 4ed65ecb6e..3493fcbc9e 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -582,6 +582,8 @@ DECL_TEMPLATE(amd64_linux, sys_shmdt); DECL_TEMPLATE(amd64_linux, sys_shmdt); DECL_TEMPLATE(amd64_linux, sys_shmctl); DECL_TEMPLATE(amd64_linux, sys_arch_prctl); +DECL_TEMPLATE(amd64_linux, sys_pread64); +DECL_TEMPLATE(amd64_linux, sys_pwrite64); PRE(sys_clone) @@ -1049,6 +1051,35 @@ POST(sys_shmctl) ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3); } +PRE(sys_pread64) +{ + *flags |= SfMayBlock; + PRINT("sys_pread64 ( %d, %p, %llu, %lld )", + ARG1, ARG2, (ULong)ARG3, ARG4); + PRE_REG_READ4(ssize_t, "pread64", + unsigned int, fd, char *, buf, + vki_size_t, count, vki_loff_t, offset); + PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 ); +} +POST(sys_pread64) +{ + vg_assert(SUCCESS); + if (RES > 0) { + POST_MEM_WRITE( ARG2, RES ); + } +} + +PRE(sys_pwrite64) +{ + *flags |= SfMayBlock; + PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )", + ARG1, ARG2, (ULong)ARG3, ARG4); + PRE_REG_READ4(ssize_t, "pwrite64", + unsigned int, fd, const char *, buf, + vki_size_t, count, vki_loff_t, offset); + PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 ); +} + #undef PRE #undef POST @@ -1090,8 +1121,8 @@ const SyscallTableEntry ML_(syscall_table)[] = { PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 15 GENXY(__NR_ioctl, sys_ioctl), // 16 - GENXY(__NR_pread64, sys_pread64), // 17 - // (__NR_pwrite64, sys_pwrite64), // 18 + PLAXY(__NR_pread64, sys_pread64), // 17 + PLAX_(__NR_pwrite64, sys_pwrite64), // 18 GENXY(__NR_readv, sys_readv), // 19 GENX_(__NR_writev, sys_writev), // 20 diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 69a793d326..cc8548bd68 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -2102,8 +2102,11 @@ PRE(sys_setregid16) PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid); } -// XXX: only for 32-bit archs -#if defined(VGP_x86_linux) +// The actual kernel definition of this routine takes a +// single 64 bit offset argument. This version is for 32 bit +// platforms only and treats the offset as two values - the +// kernel relies on stack based argument passing conventions +// to merge the two together. PRE(sys_pwrite64) { *flags |= SfMayBlock; @@ -2114,7 +2117,6 @@ PRE(sys_pwrite64) vki_u32, offset_low32, vki_u32, offset_high32); PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 ); } -#endif PRE(sys_sync) { @@ -2154,9 +2156,11 @@ PRE(sys_getsid) PRE_REG_READ1(long, "getsid", vki_pid_t, pid); } -// XXX: only for 32-bit archs -// XXX even more: this in fact gets used by amd64-linux. Someone -// should look into this properly. +// The actual kernel definition of this routine takes a +// single 64 bit offset argument. This version is for 32 bit +// platforms only and treats the offset as two values - the +// kernel relies on stack based argument passing conventions +// to merge the two together. PRE(sys_pread64) { *flags |= SfMayBlock; diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index 024437af04..e499b09ebe 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -2132,8 +2132,8 @@ const SyscallTableEntry ML_(syscall_table)[] = { //.. GENXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo), // 177 //.. GENX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 178 //.. -//.. GENXY(__NR_pread64, sys_pread64), // 179 -//.. GENX_(__NR_pwrite64, sys_pwrite64), // 180 + GENXY(__NR_pread64, sys_pread64), // 179 + GENX_(__NR_pwrite64, sys_pwrite64), // 180 GENX_(__NR_chown, sys_chown16), // 181 //.. GENXY(__NR_getcwd, sys_getcwd), // 182 //.. GENXY(__NR_capget, sys_capget), // 183