mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 10:05:29 +00:00
Add support for process_vm_readv and process_vm_writev system calls.
Patch from Lénaïc Huard to fix BZ#292995. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12374
This commit is contained in:
parent
7104ded0a5
commit
74eb6fb3b4
@ -1683,6 +1683,8 @@ AC_CHECK_FUNCS([ \
|
||||
strstr \
|
||||
syscall \
|
||||
utimensat \
|
||||
process_vm_readv \
|
||||
process_vm_writev \
|
||||
])
|
||||
|
||||
# AC_CHECK_LIB adds any library found to the variable LIBS, and links these
|
||||
|
||||
@ -263,6 +263,10 @@ DECL_TEMPLATE(linux, sys_delete_module);
|
||||
// Linux-specific (oprofile-related)
|
||||
DECL_TEMPLATE(linux, sys_lookup_dcookie); // (*/32/64) L
|
||||
|
||||
// Linux-specific (new in Linux 3.2)
|
||||
DECL_TEMPLATE(linux, sys_process_vm_readv);
|
||||
DECL_TEMPLATE(linux, sys_process_vm_writev);
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
Wrappers for sockets and ipc-ery. These are split into standalone
|
||||
procedures because x86-linux hides them inside multiplexors
|
||||
|
||||
@ -1423,7 +1423,10 @@ static SyscallTableEntry syscall_table[] = {
|
||||
// LINX_(__NR_syncfs, sys_ni_syscall), // 306
|
||||
// LINX_(__NR_sendmmsg, sys_ni_syscall), // 307
|
||||
// LINX_(__NR_setns, sys_ni_syscall), // 308
|
||||
LINXY(__NR_getcpu, sys_getcpu) // 309
|
||||
LINXY(__NR_getcpu, sys_getcpu), // 309
|
||||
|
||||
LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 310
|
||||
LINX_(__NR_process_vm_writev, sys_process_vm_writev) // 311
|
||||
};
|
||||
|
||||
SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
|
||||
|
||||
@ -3471,6 +3471,73 @@ PRE(sys_pwritev)
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
process_vm_{read,write}v wrappers
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
PRE(sys_process_vm_readv)
|
||||
{
|
||||
PRINT("sys_process_vm_readv ( %lu, %#lx, %lu, %#lx, %lu, %lu )",
|
||||
ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
|
||||
PRE_REG_READ6(ssize_t, "process_vm_readv",
|
||||
vki_pid_t, pid,
|
||||
const struct iovec *, lvec,
|
||||
unsigned long, liovcnt,
|
||||
const struct iovec *, rvec,
|
||||
unsigned long, riovcnt,
|
||||
unsigned long, flags);
|
||||
PRE_MEM_READ( "process_vm_readv(lvec)",
|
||||
ARG2, ARG3 * sizeof(struct vki_iovec) );
|
||||
PRE_MEM_READ( "process_vm_readv(rvec)",
|
||||
ARG4, ARG5 * sizeof(struct vki_iovec) );
|
||||
if (ARG2 != 0) {
|
||||
/* TODO: Don't do any of the following if lvec is invalid */
|
||||
const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
|
||||
UInt i;
|
||||
for (i = 0; i < ARG3; i++)
|
||||
PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
|
||||
(Addr)vec[i].iov_base, vec[i].iov_len );
|
||||
}
|
||||
}
|
||||
|
||||
POST(sys_process_vm_readv)
|
||||
{
|
||||
const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
|
||||
UInt remains = RES;
|
||||
UInt i;
|
||||
for (i = 0; i < ARG3; i++) {
|
||||
UInt nReadThisBuf = vec[i].iov_len <= remains ?
|
||||
vec[i].iov_len : remains;
|
||||
POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
|
||||
remains -= nReadThisBuf;
|
||||
}
|
||||
}
|
||||
|
||||
PRE(sys_process_vm_writev)
|
||||
{
|
||||
PRINT("sys_process_vm_writev ( %lu, %#lx, %lu, %#lx, %lu, %lu )",
|
||||
ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
|
||||
PRE_REG_READ6(ssize_t, "process_vm_writev",
|
||||
vki_pid_t, pid,
|
||||
const struct iovec *, lvec,
|
||||
unsigned long, liovcnt,
|
||||
const struct iovec *, rvec,
|
||||
unsigned long, riovcnt,
|
||||
unsigned long, flags);
|
||||
PRE_MEM_READ( "process_vm_writev(lvec)",
|
||||
ARG2, ARG3 * sizeof(struct vki_iovec) );
|
||||
PRE_MEM_READ( "process_vm_writev(rvec)",
|
||||
ARG4, ARG5 * sizeof(struct vki_iovec) );
|
||||
if (ARG2 != 0) {
|
||||
/* TODO: Don't do any of the following if lvec is invalid */
|
||||
const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
|
||||
UInt i;
|
||||
for (i = 0; i < ARG3; i++)
|
||||
PRE_MEM_READ( "process_vm_writev(lvec[...])",
|
||||
(Addr)vec[i].iov_base, vec[i].iov_len );
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
key retention service wrappers
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
@ -1827,7 +1827,10 @@ static SyscallTableEntry syscall_table[] = {
|
||||
LINXY(__NR_perf_event_open, sys_perf_event_open), // 319
|
||||
LINXY(__NR_preadv, sys_preadv), // 320
|
||||
LINX_(__NR_pwritev, sys_pwritev), // 321
|
||||
LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) // 322
|
||||
LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 322
|
||||
|
||||
LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 351
|
||||
LINX_(__NR_process_vm_writev, sys_process_vm_writev) // 352
|
||||
};
|
||||
|
||||
SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
|
||||
|
||||
@ -1467,7 +1467,10 @@ static SyscallTableEntry syscall_table[] = {
|
||||
LINXY(__NR_perf_event_open, sys_perf_event_open), // 319
|
||||
LINXY(__NR_preadv, sys_preadv), // 320
|
||||
LINX_(__NR_pwritev, sys_pwritev), // 321
|
||||
LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) // 322
|
||||
LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 322
|
||||
|
||||
LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 351
|
||||
LINX_(__NR_process_vm_writev, sys_process_vm_writev) // 352
|
||||
};
|
||||
|
||||
SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
|
||||
|
||||
@ -2223,7 +2223,7 @@ static SyscallTableEntry syscall_table[] = {
|
||||
// LINX_(__NR_fanotify_init, sys_ni_syscall), // 338
|
||||
// LINX_(__NR_fanotify_mark, sys_ni_syscall), // 339
|
||||
|
||||
LINXY(__NR_prlimit64, sys_prlimit64) // 340
|
||||
LINXY(__NR_prlimit64, sys_prlimit64), // 340
|
||||
// LINX_(__NR_name_to_handle_at, sys_ni_syscall), // 341
|
||||
// LINX_(__NR_open_by_handle_at, sys_ni_syscall), // 342
|
||||
// LINX_(__NR_clock_adjtime, sys_ni_syscall), // 343
|
||||
@ -2231,6 +2231,8 @@ static SyscallTableEntry syscall_table[] = {
|
||||
|
||||
// LINX_(__NR_sendmmsg, sys_ni_syscall), // 345
|
||||
// LINX_(__NR_setns, sys_ni_syscall), // 346
|
||||
LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 347
|
||||
LINX_(__NR_process_vm_writev, sys_process_vm_writev) // 348
|
||||
};
|
||||
|
||||
SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
|
||||
|
||||
@ -1257,6 +1257,14 @@ int main(void)
|
||||
GO(__NR_epoll_create1, "1s 0m");
|
||||
SY(__NR_epoll_create1, x0); SUCC_OR_FAIL;
|
||||
|
||||
// __NR_process_vm_readv 347
|
||||
GO(__NR_process_vm_readv, "6s 2m");
|
||||
SY(__NR_process_vm_readv, x0, x0, x0+1, x0, x0+1, x0); FAIL;
|
||||
|
||||
// __NR_process_vm_writev 348
|
||||
GO(__NR_process_vm_writev, "6s 2m");
|
||||
SY(__NR_process_vm_writev, x0, x0, x0+1, x0, x0+1, x0); FAIL;
|
||||
|
||||
// no such syscall...
|
||||
GO(9999, "1e");
|
||||
SY(9999); FAIL;
|
||||
|
||||
@ -3977,6 +3977,80 @@ Syscall param epoll_create1(flags) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1258)
|
||||
|
||||
-----------------------------------------------------
|
||||
347:__NR_process_vm_readv 6s 2m
|
||||
-----------------------------------------------------
|
||||
Syscall param process_vm_readv(pid) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1262)
|
||||
|
||||
Syscall param process_vm_readv(lvec) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1262)
|
||||
|
||||
Syscall param process_vm_readv(liovcnt) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1262)
|
||||
|
||||
Syscall param process_vm_readv(rvec) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1262)
|
||||
|
||||
Syscall param process_vm_readv(riovcnt) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1262)
|
||||
|
||||
Syscall param process_vm_readv(flags) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1262)
|
||||
|
||||
Syscall param process_vm_readv(lvec) points to unaddressable byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1262)
|
||||
Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
|
||||
Syscall param process_vm_readv(rvec) points to unaddressable byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1262)
|
||||
Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
|
||||
-----------------------------------------------------
|
||||
348:__NR_process_vm_writev 6s 2m
|
||||
-----------------------------------------------------
|
||||
Syscall param process_vm_writev(pid) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1266)
|
||||
|
||||
Syscall param process_vm_writev(lvec) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1266)
|
||||
|
||||
Syscall param process_vm_writev(liovcnt) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1266)
|
||||
|
||||
Syscall param process_vm_writev(rvec) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1266)
|
||||
|
||||
Syscall param process_vm_writev(riovcnt) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1266)
|
||||
|
||||
Syscall param process_vm_writev(flags) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1266)
|
||||
|
||||
Syscall param process_vm_writev(lvec) points to unaddressable byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1266)
|
||||
Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
|
||||
Syscall param process_vm_writev(rvec) points to unaddressable byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1266)
|
||||
Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
|
||||
-----------------------------------------------------
|
||||
9999: 9999 1e
|
||||
-----------------------------------------------------
|
||||
@ -3990,5 +4064,5 @@ it at http://valgrind.org/support/bug_reports.html.
|
||||
-----------------------------------------------------
|
||||
Syscall param exit(status) contains uninitialised byte(s)
|
||||
...
|
||||
by 0x........: main (scalar.c:1266)
|
||||
by 0x........: main (scalar.c:1274)
|
||||
|
||||
|
||||
@ -160,7 +160,8 @@ EXTRA_DIST = \
|
||||
threadederrno.vgtest \
|
||||
timestamp.stderr.exp timestamp.vgtest \
|
||||
tls.vgtest tls.stderr.exp tls.stdout.exp \
|
||||
vgprintf.stderr.exp vgprintf.vgtest
|
||||
vgprintf.stderr.exp vgprintf.vgtest \
|
||||
process_vm_readv_writev.stderr.exp process_vm_readv_writev.vgtest
|
||||
|
||||
check_PROGRAMS = \
|
||||
ansi args \
|
||||
@ -198,7 +199,8 @@ check_PROGRAMS = \
|
||||
valgrind_cpp_test \
|
||||
vgprintf \
|
||||
coolo_sigaction \
|
||||
gxx304
|
||||
gxx304 \
|
||||
process_vm_readv_writev
|
||||
|
||||
# DDD:
|
||||
# - manythreads and thread-exits have lots of this:
|
||||
|
||||
92
none/tests/process_vm_readv_writev.c
Normal file
92
none/tests/process_vm_readv_writev.c
Normal file
@ -0,0 +1,92 @@
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
static int status = EXIT_SUCCESS;
|
||||
|
||||
#ifdef HAVE_PROCESS_VM_READV
|
||||
|
||||
static void test_process_vm_readv()
|
||||
{
|
||||
char lbuf[] = "123456";
|
||||
char rbuf[] = "ABCDEF";
|
||||
|
||||
struct iovec lvec[2];
|
||||
struct iovec rvec[2];
|
||||
|
||||
lvec[0].iov_base = lbuf + 1;
|
||||
lvec[0].iov_len = 1;
|
||||
lvec[1].iov_base = lbuf + 3;
|
||||
lvec[1].iov_len = 2;
|
||||
|
||||
rvec[0].iov_base = rbuf + 1;
|
||||
rvec[0].iov_len = 2;
|
||||
rvec[1].iov_base = rbuf + 4;
|
||||
rvec[1].iov_len = 1;
|
||||
|
||||
if (process_vm_readv(getpid(),
|
||||
lvec, 2,
|
||||
rvec, 2,
|
||||
0 ) < 0 ) {
|
||||
perror("process_vm_readv");
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (strcmp(lbuf, "1B3CE6") != 0) {
|
||||
fprintf(stderr, "Expected: \"1B3CE6\"; Got: \"%s\"\n", lbuf);
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined( HAVE_PROCESS_VM_READV ) */
|
||||
|
||||
#ifdef HAVE_PROCESS_VM_WRITEV
|
||||
|
||||
static void test_process_vm_writev()
|
||||
{
|
||||
char lbuf[] = "123456";
|
||||
char rbuf[] = "ABCDEF";
|
||||
|
||||
struct iovec lvec[2];
|
||||
struct iovec rvec[2];
|
||||
|
||||
lvec[0].iov_base = lbuf + 1;
|
||||
lvec[0].iov_len = 1;
|
||||
lvec[1].iov_base = lbuf + 3;
|
||||
lvec[1].iov_len = 2;
|
||||
|
||||
rvec[0].iov_base = rbuf + 1;
|
||||
rvec[0].iov_len = 2;
|
||||
rvec[1].iov_base = rbuf + 4;
|
||||
rvec[1].iov_len = 1;
|
||||
|
||||
if (process_vm_writev(getpid(),
|
||||
lvec, 2,
|
||||
rvec, 2,
|
||||
0 ) < 0 ) {
|
||||
perror("process_vm_writev");
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (strcmp(rbuf, "A24D5F") != 0) {
|
||||
fprintf(stderr, "Expected: \"A24D5F\"; Got: \"%s\"\n", rbuf);
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined( HAVE_PROCESS_VM_WRITEV ) */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef HAVE_PROCESS_VM_READV
|
||||
test_process_vm_readv();
|
||||
#endif
|
||||
#ifdef HAVE_PROCESS_VM_WRITEV
|
||||
test_process_vm_writev();
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
2
none/tests/process_vm_readv_writev.stderr.exp
Normal file
2
none/tests/process_vm_readv_writev.stderr.exp
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
1
none/tests/process_vm_readv_writev.vgtest
Normal file
1
none/tests/process_vm_readv_writev.vgtest
Normal file
@ -0,0 +1 @@
|
||||
prog: process_vm_readv_writev
|
||||
Loading…
x
Reference in New Issue
Block a user