import valgrind-3.15.0-11.el8
This commit is contained in:
parent
a5d01916f0
commit
313a11be3e
751
SOURCES/valgrind-3.15.0-preadv2-pwritev2.patch
Normal file
751
SOURCES/valgrind-3.15.0-preadv2-pwritev2.patch
Normal file
@ -0,0 +1,751 @@
|
||||
commit b0861063a8d2a55bb7423e90d26806bab0f78a12
|
||||
Author: Alexandra Hájková <ahajkova@redhat.com>
|
||||
Date: Tue Jun 4 13:47:14 2019 +0200
|
||||
|
||||
Add support for preadv2 and pwritev2 syscalls
|
||||
|
||||
Support for amd64, x86 - 64 and 32 bit, arm64, ppc64, ppc64le,
|
||||
s390x, mips64. This should work identically on all
|
||||
arches, tested on x86 32bit and 64bit one, but enabled on all.
|
||||
|
||||
Refactor the code to be reusable between old/new syscalls. Resolve TODO
|
||||
items in the code. Add the testcase for the preadv2/pwritev2 and also
|
||||
add the (similar) testcase for the older preadv/pwritev syscalls.
|
||||
|
||||
Trying to test handling an uninitialized flag argument for the v2 syscalls
|
||||
does not work because the flag always comes out as defined zero.
|
||||
Turns out glibc does this deliberately on 64bit architectures because
|
||||
the kernel does actually have a low_offset and high_offset argument, but
|
||||
ignores the high_offset/assumes it is zero.
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=601cc11d054ae4b5e9b5babec3d8e4667a2cb9b5
|
||||
|
||||
https://bugs.kde.org/408414
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 352892565..3596d2fec 100755
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -4173,6 +4173,10 @@ AC_CHECK_FUNCS([ \
|
||||
process_vm_readv \
|
||||
process_vm_writev \
|
||||
copy_file_range \
|
||||
+ preadv \
|
||||
+ pwritev \
|
||||
+ preadv2 \
|
||||
+ pwritev2 \
|
||||
])
|
||||
|
||||
# AC_CHECK_LIB adds any library found to the variable LIBS, and links these
|
||||
@@ -4190,6 +4194,10 @@ AM_CONDITIONAL([HAVE_PTHREAD_SETNAME_NP],
|
||||
[test x$ac_cv_func_pthread_setname_np = xyes])
|
||||
AM_CONDITIONAL([HAVE_COPY_FILE_RANGE],
|
||||
[test x$ac_cv_func_copy_file_range = xyes])
|
||||
+AM_CONDITIONAL([HAVE_PREADV_PWRITEV],
|
||||
+ [test x$ac_cv_func_preadv = xyes && test x$ac_cv_func_pwritev = xyes])
|
||||
+AM_CONDITIONAL([HAVE_PREADV2_PWRITEV2],
|
||||
+ [test x$ac_cv_func_preadv2 = xyes && test x$ac_cv_func_pwritev2 = xyes])
|
||||
|
||||
if test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX \
|
||||
-o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX ; then
|
||||
diff --git a/coregrind/m_syswrap/priv_syswrap-generic.h b/coregrind/m_syswrap/priv_syswrap-generic.h
|
||||
index 3e1c8b682..73f9224f7 100644
|
||||
--- a/coregrind/m_syswrap/priv_syswrap-generic.h
|
||||
+++ b/coregrind/m_syswrap/priv_syswrap-generic.h
|
||||
@@ -109,6 +109,19 @@ ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename,
|
||||
/* Helper function for generic mprotect and linux pkey_mprotect. */
|
||||
extern void handle_sys_mprotect (ThreadId tid, SyscallStatus *status,
|
||||
Addr *addr, SizeT *len, Int *prot);
|
||||
+/* Helper functions for preadv/preadv2. */
|
||||
+extern
|
||||
+void handle_pre_sys_preadv(ThreadId tid, SyscallStatus* status,
|
||||
+ Int fd, Addr vector, Int count,
|
||||
+ const char *str);
|
||||
+extern
|
||||
+void handle_post_sys_preadv(ThreadId tid, SyscallStatus* status, Addr vector, Int count);
|
||||
+
|
||||
+/* Helper function for pwritev/pwritev2. */
|
||||
+extern
|
||||
+void handle_sys_pwritev(ThreadId tid, SyscallStatus* status,
|
||||
+ Int fd, Addr vector, Int count,
|
||||
+ const char *str);
|
||||
|
||||
DECL_TEMPLATE(generic, sys_ni_syscall); // * P -- unimplemented
|
||||
DECL_TEMPLATE(generic, sys_exit);
|
||||
diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h
|
||||
index be2f9bdde..8ce8ef3d5 100644
|
||||
--- a/coregrind/m_syswrap/priv_syswrap-linux.h
|
||||
+++ b/coregrind/m_syswrap/priv_syswrap-linux.h
|
||||
@@ -46,7 +46,9 @@ DECL_TEMPLATE(linux, sys_oldumount);
|
||||
DECL_TEMPLATE(linux, sys_umount);
|
||||
DECL_TEMPLATE(linux, sys_perf_event_open);
|
||||
DECL_TEMPLATE(linux, sys_preadv);
|
||||
+DECL_TEMPLATE(linux, sys_preadv2);
|
||||
DECL_TEMPLATE(linux, sys_pwritev);
|
||||
+DECL_TEMPLATE(linux, sys_pwritev2);
|
||||
DECL_TEMPLATE(linux, sys_sendmmsg);
|
||||
DECL_TEMPLATE(linux, sys_recvmmsg);
|
||||
DECL_TEMPLATE(linux, sys_dup3);
|
||||
diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c
|
||||
index 382dc65cf..9b8068d0f 100644
|
||||
--- a/coregrind/m_syswrap/syswrap-amd64-linux.c
|
||||
+++ b/coregrind/m_syswrap/syswrap-amd64-linux.c
|
||||
@@ -857,6 +857,8 @@ static SyscallTableEntry syscall_table[] = {
|
||||
// LIN__(__NR_kexec_file_load, sys_ni_syscall), // 320
|
||||
LINXY(__NR_bpf, sys_bpf), // 321
|
||||
|
||||
+ LINXY(__NR_preadv2, sys_preadv2), // 327
|
||||
+ LINX_(__NR_pwritev2, sys_pwritev2), // 328
|
||||
|
||||
LINXY(__NR_statx, sys_statx), // 332
|
||||
|
||||
diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c
|
||||
index c700e3dbe..d12d40632 100644
|
||||
--- a/coregrind/m_syswrap/syswrap-arm64-linux.c
|
||||
+++ b/coregrind/m_syswrap/syswrap-arm64-linux.c
|
||||
@@ -818,8 +818,8 @@ static SyscallTableEntry syscall_main_table[] = {
|
||||
LINX_(__NR_membarrier, sys_membarrier), // 283
|
||||
// (__NR_mlock2, sys_ni_syscall), // 284
|
||||
LINX_(__NR_copy_file_range, sys_copy_file_range), // 285
|
||||
- // (__NR_preadv2, sys_ni_syscall), // 286
|
||||
- // (__NR_pwritev2, sys_ni_syscall), // 287
|
||||
+ LINX_(__NR_preadv2, sys_ni_syscall), // 286
|
||||
+ LINX_(__NR_pwritev2, sys_ni_syscall), // 287
|
||||
// (__NR_pkey_mprotect, sys_ni_syscall), // 288
|
||||
// (__NR_pkey_alloc, sys_ni_syscall), // 289
|
||||
// (__NR_pkey_free, sys_ni_syscall), // 290
|
||||
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
|
||||
index 36d09d6e0..2fe15d97b 100644
|
||||
--- a/coregrind/m_syswrap/syswrap-linux.c
|
||||
+++ b/coregrind/m_syswrap/syswrap-linux.c
|
||||
@@ -5501,12 +5501,57 @@ POST(sys_open_by_handle_at)
|
||||
/* ---------------------------------------------------------------------
|
||||
p{read,write}v wrappers
|
||||
------------------------------------------------------------------ */
|
||||
+/* This handles the common part of the PRE macro for preadv and preadv2. */
|
||||
+void handle_pre_sys_preadv(ThreadId tid, SyscallStatus* status,
|
||||
+ Int fd, Addr vector, Int count, const char *str)
|
||||
+{
|
||||
+ struct vki_iovec * vec;
|
||||
+ Int i;
|
||||
+ /* safe size for the "preadv/preadv2(vector[i])" string */
|
||||
+ char tmp[30];
|
||||
+
|
||||
+ if (!ML_(fd_allowed)(fd, str, tid, False)) {
|
||||
+ SET_STATUS_Failure( VKI_EBADF );
|
||||
+ } else if (count > 0) {
|
||||
+ VG_(strcpy) (tmp, str);
|
||||
+ VG_(strcat) (tmp, "(vector)");
|
||||
+ PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
|
||||
+
|
||||
+ if (ML_(safe_to_deref) ((void *)(Addr)vector,
|
||||
+ count * sizeof(struct vki_iovec))) {
|
||||
+ vec = (struct vki_iovec *)(Addr)vector;
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
|
||||
+ PRE_MEM_WRITE( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* This handles the common part of the POST macro for preadv and preadv2. */
|
||||
+void handle_post_sys_preadv(ThreadId tid, SyscallStatus* status, Addr vector, Int count)
|
||||
+{
|
||||
+ vg_assert(SUCCESS);
|
||||
+ if (RES > 0) {
|
||||
+ Int i;
|
||||
+ struct vki_iovec * vec = (struct vki_iovec *)(Addr)vector;
|
||||
+ Int remains = RES;
|
||||
+
|
||||
+ /* RES holds the number of bytes read. */
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ Int nReadThisBuf = vec[i].iov_len;
|
||||
+ if (nReadThisBuf > remains) nReadThisBuf = remains;
|
||||
+ POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
|
||||
+ remains -= nReadThisBuf;
|
||||
+ if (remains < 0) VG_(core_panic)("preadv: remains < 0");
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
|
||||
PRE(sys_preadv)
|
||||
{
|
||||
- Int i;
|
||||
- struct vki_iovec * vec;
|
||||
*flags |= SfMayBlock;
|
||||
+ const char *str = "preadv";
|
||||
#if VG_WORDSIZE == 4
|
||||
/* Note that the offset argument here is in lo+hi order on both
|
||||
big and little endian platforms... */
|
||||
@@ -5525,45 +5570,89 @@ PRE(sys_preadv)
|
||||
#else
|
||||
# error Unexpected word size
|
||||
#endif
|
||||
- if (!ML_(fd_allowed)(ARG1, "preadv", tid, False)) {
|
||||
- SET_STATUS_Failure( VKI_EBADF );
|
||||
- } else {
|
||||
- PRE_MEM_READ( "preadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
|
||||
+ Int fd = ARG1;
|
||||
+ Addr vector = ARG2;
|
||||
+ Int count = ARG3;
|
||||
+
|
||||
+ handle_pre_sys_preadv(tid, status, fd, vector, count, str);
|
||||
|
||||
- if (ARG2 != 0) {
|
||||
- /* ToDo: don't do any of the following if the vector is invalid */
|
||||
- vec = (struct vki_iovec *)(Addr)ARG2;
|
||||
- for (i = 0; i < (Int)ARG3; i++)
|
||||
- PRE_MEM_WRITE( "preadv(vector[...])",
|
||||
- (Addr)vec[i].iov_base, vec[i].iov_len );
|
||||
- }
|
||||
- }
|
||||
}
|
||||
|
||||
POST(sys_preadv)
|
||||
{
|
||||
- vg_assert(SUCCESS);
|
||||
- if (RES > 0) {
|
||||
- Int i;
|
||||
- struct vki_iovec * vec = (struct vki_iovec *)(Addr)ARG2;
|
||||
- Int remains = RES;
|
||||
+ Addr vector = ARG2;
|
||||
+ Int count = ARG3;
|
||||
|
||||
- /* RES holds the number of bytes read. */
|
||||
- for (i = 0; i < (Int)ARG3; i++) {
|
||||
- Int nReadThisBuf = vec[i].iov_len;
|
||||
- if (nReadThisBuf > remains) nReadThisBuf = remains;
|
||||
- POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
|
||||
- remains -= nReadThisBuf;
|
||||
- if (remains < 0) VG_(core_panic)("preadv: remains < 0");
|
||||
+ handle_post_sys_preadv(tid, status, vector, count);
|
||||
+}
|
||||
+
|
||||
+PRE(sys_preadv2)
|
||||
+{
|
||||
+ *flags |= SfMayBlock;
|
||||
+ const char *str = "preadv2";
|
||||
+#if VG_WORDSIZE == 4
|
||||
+ /* Note that the offset argument here is in lo+hi order on both
|
||||
+ big and little endian platforms... */
|
||||
+ PRINT("sys_preadv2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
|
||||
+ "u, %lld, %" FMT_REGWORD "u )",
|
||||
+ ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
|
||||
+ PRE_REG_READ6(ssize_t, "preadv2",
|
||||
+ unsigned long, fd, const struct iovec *, vector,
|
||||
+ unsigned long, count, vki_u32, offset_low,
|
||||
+ vki_u32, offset_high, unsigned long, flags);
|
||||
+#elif VG_WORDSIZE == 8
|
||||
+ PRINT("sys_preadv2 ( %lu, %#lx, %lu, %ld, %lu )", ARG1, ARG2, ARG3, SARG4, ARG5);
|
||||
+ PRE_REG_READ5(ssize_t, "preadv2",
|
||||
+ unsigned long, fd, const struct iovec *, vector,
|
||||
+ unsigned long, count, Word, offset, unsigned long, flags);
|
||||
+#else
|
||||
+# error Unexpected word size
|
||||
+#endif
|
||||
+ Int fd = ARG1;
|
||||
+ Addr vector = ARG2;
|
||||
+ Int count = ARG3;
|
||||
+
|
||||
+ handle_pre_sys_preadv(tid, status, fd, vector, count, str);
|
||||
+}
|
||||
+
|
||||
+POST(sys_preadv2)
|
||||
+{
|
||||
+ Addr vector = ARG2;
|
||||
+ Int count = ARG3;
|
||||
+
|
||||
+ handle_post_sys_preadv(tid, status, vector, count);
|
||||
+}
|
||||
+
|
||||
+/* This handles the common part of the PRE macro for pwritev and pwritev2. */
|
||||
+void handle_sys_pwritev(ThreadId tid, SyscallStatus* status,
|
||||
+ Int fd, Addr vector, Int count, const char *str)
|
||||
+{
|
||||
+ Int i;
|
||||
+ struct vki_iovec * vec;
|
||||
+ /* safe size for the "preadv/preadv2(vector[i])" string */
|
||||
+ char tmp[30];
|
||||
+
|
||||
+ if (!ML_(fd_allowed)(fd, str, tid, False)) {
|
||||
+ SET_STATUS_Failure( VKI_EBADF );
|
||||
+ } else if (count > 0) {
|
||||
+ VG_(strcpy) (tmp, str);
|
||||
+ VG_(strcat) (tmp, "(vector)");
|
||||
+ PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
|
||||
+ if (ML_(safe_to_deref) ((void *)(Addr)vector,
|
||||
+ count * sizeof(struct vki_iovec))) {
|
||||
+ vec = (struct vki_iovec *)(Addr)vector;
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
|
||||
+ PRE_MEM_READ( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRE(sys_pwritev)
|
||||
{
|
||||
- Int i;
|
||||
- struct vki_iovec * vec;
|
||||
*flags |= SfMayBlock;
|
||||
+ const char *str = "pwritev";
|
||||
#if VG_WORDSIZE == 4
|
||||
/* Note that the offset argument here is in lo+hi order on both
|
||||
big and little endian platforms... */
|
||||
@@ -5581,19 +5670,41 @@ PRE(sys_pwritev)
|
||||
#else
|
||||
# error Unexpected word size
|
||||
#endif
|
||||
- if (!ML_(fd_allowed)(ARG1, "pwritev", tid, False)) {
|
||||
- SET_STATUS_Failure( VKI_EBADF );
|
||||
- } else {
|
||||
- PRE_MEM_READ( "pwritev(vector)",
|
||||
- ARG2, ARG3 * sizeof(struct vki_iovec) );
|
||||
- if (ARG2 != 0) {
|
||||
- /* ToDo: don't do any of the following if the vector is invalid */
|
||||
- vec = (struct vki_iovec *)(Addr)ARG2;
|
||||
- for (i = 0; i < (Int)ARG3; i++)
|
||||
- PRE_MEM_READ( "pwritev(vector[...])",
|
||||
- (Addr)vec[i].iov_base, vec[i].iov_len );
|
||||
- }
|
||||
- }
|
||||
+ Int fd = ARG1;
|
||||
+ Addr vector = ARG2;
|
||||
+ Int count = ARG3;
|
||||
+
|
||||
+ handle_sys_pwritev(tid, status, fd, vector, count, str);
|
||||
+}
|
||||
+
|
||||
+PRE(sys_pwritev2)
|
||||
+{
|
||||
+ *flags |= SfMayBlock;
|
||||
+ const char *str = "pwritev2";
|
||||
+#if VG_WORDSIZE == 4
|
||||
+ /* Note that the offset argument here is in lo+hi order on both
|
||||
+ big and little endian platforms... */
|
||||
+ PRINT("sys_pwritev2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
|
||||
+ "u, %lld, %" FMT_REGWORD "u )",
|
||||
+ ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
|
||||
+ PRE_REG_READ6(ssize_t, "pwritev2",
|
||||
+ unsigned long, fd, const struct iovec *, vector,
|
||||
+ unsigned long, count, vki_u32, offset_low,
|
||||
+ vki_u32, offset_high, unsigned long, flags);
|
||||
+#elif VG_WORDSIZE == 8
|
||||
+ /* Note offset_high isn't actually used? */
|
||||
+ PRE_REG_READ6(ssize_t, "pwritev2",
|
||||
+ unsigned long, fd, const struct iovec *, vector,
|
||||
+ unsigned long, count, Word, offset,
|
||||
+ Word, offset_high, unsigned long, flags);
|
||||
+#else
|
||||
+# error Unexpected word size
|
||||
+#endif
|
||||
+ Int fd = ARG1;
|
||||
+ Addr vector = ARG2;
|
||||
+ Int count = ARG3;
|
||||
+
|
||||
+ handle_sys_pwritev(tid, status, fd, vector, count, str);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c
|
||||
index baa2934ab..d65a664dd 100644
|
||||
--- a/coregrind/m_syswrap/syswrap-ppc64-linux.c
|
||||
+++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c
|
||||
@@ -1006,6 +1006,8 @@ static SyscallTableEntry syscall_table[] = {
|
||||
LINX_(__NR_membarrier, sys_membarrier), // 365
|
||||
|
||||
LINX_(__NR_copy_file_range, sys_copy_file_range), // 379
|
||||
+ LINX_(__NR_preadv2, sys_preadv2), // 380
|
||||
+ LINX_(__NR_pwritev2, sys_pwritev2), // 381
|
||||
|
||||
LINXY(__NR_statx, sys_statx), // 383
|
||||
};
|
||||
diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c
|
||||
index 1481e768b..3354d41c0 100644
|
||||
--- a/coregrind/m_syswrap/syswrap-s390x-linux.c
|
||||
+++ b/coregrind/m_syswrap/syswrap-s390x-linux.c
|
||||
@@ -853,6 +853,8 @@ static SyscallTableEntry syscall_table[] = {
|
||||
LINX_(__NR_shutdown, sys_shutdown), // 373
|
||||
|
||||
LINX_(__NR_copy_file_range, sys_copy_file_range), // 375
|
||||
+ LINXY(__NR_preadv2, sys_preadv2), // 376
|
||||
+ LINX_(__NR_pwritev2, sys_pwritev2), // 377
|
||||
|
||||
LINXY(__NR_statx, sys_statx), // 379
|
||||
};
|
||||
diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c
|
||||
index 9ff53a92a..33d1213a3 100644
|
||||
--- a/coregrind/m_syswrap/syswrap-x86-linux.c
|
||||
+++ b/coregrind/m_syswrap/syswrap-x86-linux.c
|
||||
@@ -1607,6 +1607,8 @@ static SyscallTableEntry syscall_table[] = {
|
||||
LINX_(__NR_membarrier, sys_membarrier), // 375
|
||||
|
||||
LINX_(__NR_copy_file_range, sys_copy_file_range), // 377
|
||||
+ LINXY(__NR_preadv2, sys_preadv2), // 378
|
||||
+ LINX_(__NR_pwritev2, sys_pwritev2), // 379
|
||||
|
||||
LINXY(__NR_pkey_mprotect, sys_pkey_mprotect), // 380
|
||||
LINX_(__NR_pkey_alloc, sys_pkey_alloc), // 381
|
||||
diff --git a/memcheck/tests/linux/Makefile.am b/memcheck/tests/linux/Makefile.am
|
||||
index 00e99a52a..e13325869 100644
|
||||
--- a/memcheck/tests/linux/Makefile.am
|
||||
+++ b/memcheck/tests/linux/Makefile.am
|
||||
@@ -26,7 +26,9 @@ EXTRA_DIST = \
|
||||
timerfd-syscall.vgtest timerfd-syscall.stderr.exp \
|
||||
with-space.stderr.exp with-space.stdout.exp with-space.vgtest \
|
||||
proc-auxv.vgtest proc-auxv.stderr.exp getregset.vgtest \
|
||||
- getregset.stderr.exp getregset.stdout.exp
|
||||
+ getregset.stderr.exp getregset.stdout.exp \
|
||||
+ sys-preadv_pwritev.vgtest sys-preadv_pwritev.stderr.exp \
|
||||
+ sys-preadv2_pwritev2.vgtest sys-preadv2_pwritev2.stderr.exp
|
||||
|
||||
check_PROGRAMS = \
|
||||
brk \
|
||||
@@ -54,6 +56,14 @@ if HAVE_COPY_FILE_RANGE
|
||||
check_PROGRAMS += sys-copy_file_range
|
||||
endif
|
||||
|
||||
+if HAVE_PREADV_PWRITEV
|
||||
+ check_PROGRAMS += sys-preadv_pwritev
|
||||
+endif
|
||||
+
|
||||
+if HAVE_PREADV2_PWRITEV2
|
||||
+ check_PROGRAMS += sys-preadv2_pwritev2
|
||||
+endif
|
||||
+
|
||||
AM_CFLAGS += $(AM_FLAG_M3264_PRI)
|
||||
AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
|
||||
|
||||
diff --git a/memcheck/tests/linux/sys-preadv2_pwritev2.c b/memcheck/tests/linux/sys-preadv2_pwritev2.c
|
||||
new file mode 100644
|
||||
index 000000000..942eab68b
|
||||
--- /dev/null
|
||||
+++ b/memcheck/tests/linux/sys-preadv2_pwritev2.c
|
||||
@@ -0,0 +1,79 @@
|
||||
+#define _GNU_SOURCE
|
||||
+#include <fcntl.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/syscall.h>
|
||||
+#include <sys/uio.h>
|
||||
+#include <string.h>
|
||||
+#include "../../memcheck.h"
|
||||
+
|
||||
+#include <errno.h>
|
||||
+
|
||||
+int main(int argc, char **argv)
|
||||
+{
|
||||
+ char str0[] = "hello ";
|
||||
+ char str1[] = "world\n";
|
||||
+ struct iovec iov[2];
|
||||
+ int fd;
|
||||
+
|
||||
+ fd = open("prwv2_source", O_CREAT | O_RDWR, 0644);
|
||||
+ if (fd == -1) {
|
||||
+ perror("prwv2_source");
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ iov[0].iov_base = str0;
|
||||
+ iov[0].iov_len = strlen(str0);
|
||||
+ iov[1].iov_base = str1;
|
||||
+ iov[1].iov_len = strlen(str1);
|
||||
+
|
||||
+ /* Check pwritev2 and preadv2 called with the correct arguments works. */
|
||||
+ if (pwritev2(fd, iov, 2, 0, 0) == -1) {
|
||||
+ perror("pwritev2");
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ if (preadv2(fd, iov, 2, 0, 0) == -1) {
|
||||
+ perror("preadv2");
|
||||
+ printf("errno: %d\n", errno);
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ /* Check valgrind will produce expected warnings for the
|
||||
+ various wrong arguments. */
|
||||
+ do {
|
||||
+ /* always allocate 16 bytes to not to have different .exps for different reg sizes */
|
||||
+ char *mem = malloc(16);
|
||||
+ void *t = (void *) &mem[0];
|
||||
+ void *z = (void *) -1;
|
||||
+ int c = *((int *) &mem[4]);
|
||||
+ int flag = *((int *) &mem[8]);
|
||||
+ pwritev2(fd, NULL, 2, 0, 0);
|
||||
+ pwritev2(fd, z, 2, 0, 0);
|
||||
+ pwritev2(fd, t, 2, 0, 0);
|
||||
+ pwritev2(fd, iov, -1, 0, 0);
|
||||
+ pwritev2(fd, iov, c, 0, 0);
|
||||
+ pwritev2(fd, iov, 2, -5, 0);
|
||||
+ pwritev2(-1, iov, 2, -5, 0);
|
||||
+ pwritev2(fd, iov, 2, -5, flag);
|
||||
+
|
||||
+ preadv2(fd, NULL, 2, 0, 0);
|
||||
+ preadv2(fd, z, 2, 0, 0);
|
||||
+ preadv2(fd, t, 2, 0, 0);
|
||||
+ preadv2(fd, iov, -1, 0, 0);
|
||||
+ preadv2(fd, iov, c, 0, 0);
|
||||
+ preadv2(fd, iov, 2, -5, 0);
|
||||
+ preadv2(-1, iov, 2, -5, 0);
|
||||
+
|
||||
+ iov[1].iov_base = (void *) -1;
|
||||
+ pwritev2(fd, iov, 2, 0, 0);
|
||||
+ preadv2(fd, iov, 2, 0, 0);
|
||||
+ free(mem);
|
||||
+ } while (0);
|
||||
+
|
||||
+ close(fd);
|
||||
+ unlink("prwv2_source");
|
||||
+ exit(EXIT_SUCCESS);
|
||||
+}
|
||||
diff --git a/memcheck/tests/linux/sys-preadv2_pwritev2.stderr.exp b/memcheck/tests/linux/sys-preadv2_pwritev2.stderr.exp
|
||||
new file mode 100644
|
||||
index 000000000..e11f2a51d
|
||||
--- /dev/null
|
||||
+++ b/memcheck/tests/linux/sys-preadv2_pwritev2.stderr.exp
|
||||
@@ -0,0 +1,56 @@
|
||||
+Syscall param pwritev2(vector) points to unaddressable byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:53)
|
||||
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
+
|
||||
+Syscall param pwritev2(vector) points to unaddressable byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:54)
|
||||
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
+
|
||||
+Syscall param pwritev2(vector) points to uninitialised byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:55)
|
||||
+ Address 0x........ is 0 bytes inside a block of size 16 alloc'd
|
||||
+ at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:48)
|
||||
+
|
||||
+Syscall param pwritev2(count) contains uninitialised byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:57)
|
||||
+
|
||||
+Syscall param pwritev2(flags) contains uninitialised byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:60)
|
||||
+
|
||||
+Syscall param preadv2(vector) points to unaddressable byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:62)
|
||||
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
+
|
||||
+Syscall param preadv2(vector) points to unaddressable byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:63)
|
||||
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
+
|
||||
+Syscall param preadv2(vector) points to uninitialised byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:64)
|
||||
+ Address 0x........ is 0 bytes inside a block of size 16 alloc'd
|
||||
+ at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:48)
|
||||
+
|
||||
+Syscall param preadv2(count) contains uninitialised byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:66)
|
||||
+
|
||||
+Syscall param pwritev2(vector[1]) points to unaddressable byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:71)
|
||||
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
+
|
||||
+Syscall param preadv2(vector[1]) points to unaddressable byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv2_pwritev2.c:72)
|
||||
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
+
|
||||
diff --git a/memcheck/tests/linux/sys-preadv2_pwritev2.vgtest b/memcheck/tests/linux/sys-preadv2_pwritev2.vgtest
|
||||
new file mode 100644
|
||||
index 000000000..5cd23aacd
|
||||
--- /dev/null
|
||||
+++ b/memcheck/tests/linux/sys-preadv2_pwritev2.vgtest
|
||||
@@ -0,0 +1,3 @@
|
||||
+prereq: test -e sys-preadv2_pwritev2
|
||||
+prog: sys-preadv2_pwritev2
|
||||
+vgopts: -q
|
||||
diff --git a/memcheck/tests/linux/sys-preadv_pwritev.c b/memcheck/tests/linux/sys-preadv_pwritev.c
|
||||
new file mode 100644
|
||||
index 000000000..f5087dddc
|
||||
--- /dev/null
|
||||
+++ b/memcheck/tests/linux/sys-preadv_pwritev.c
|
||||
@@ -0,0 +1,77 @@
|
||||
+#define _GNU_SOURCE
|
||||
+#include <fcntl.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/syscall.h>
|
||||
+#include <sys/uio.h>
|
||||
+#include <string.h>
|
||||
+#include "../../memcheck.h"
|
||||
+
|
||||
+#include <errno.h>
|
||||
+
|
||||
+int main(int argc, char **argv)
|
||||
+{
|
||||
+ char str0[] = "hello ";
|
||||
+ char str1[] = "world\n";
|
||||
+ struct iovec iov[2];
|
||||
+ int fd;
|
||||
+
|
||||
+ fd = open("prwv_source", O_CREAT | O_RDWR, 0644);
|
||||
+ if (fd == -1) {
|
||||
+ perror("prwv2_source");
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ iov[0].iov_base = str0;
|
||||
+ iov[0].iov_len = strlen(str0);
|
||||
+ iov[1].iov_base = str1;
|
||||
+ iov[1].iov_len = strlen(str1);
|
||||
+
|
||||
+ /* Check pwritev and preadv called with the correct arguments works. */
|
||||
+ if (pwritev(fd, iov, 2, 0) == -1) {
|
||||
+ perror("pwritev");
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ if (preadv(fd, iov, 2, 0) == -1) {
|
||||
+ perror("preadv");
|
||||
+ printf("errno: %d\n", errno);
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ /* Check valgrind will produce expected warnings for the
|
||||
+ various wrong arguments. */
|
||||
+ do {
|
||||
+ /* always allocate 16 bytes to not to have different .exps for different reg sizes */
|
||||
+ char *mem = malloc(16);
|
||||
+ void *t = (void *) &mem[0];
|
||||
+ void *z = (void *) -1;
|
||||
+ int c = *((int *) &mem[4]);
|
||||
+ pwritev(fd, NULL, 2, 0);
|
||||
+ pwritev(fd, z, 2, 0);
|
||||
+ pwritev(fd, t, 2, 0);
|
||||
+ pwritev(fd, iov, -1, 0);
|
||||
+ pwritev(fd, iov, c, 0);
|
||||
+ pwritev(fd, iov, 2, -5);
|
||||
+ pwritev(-1, iov, 2, -5);
|
||||
+
|
||||
+ preadv(fd, NULL, 2, 0);
|
||||
+ preadv(fd, z, 2, 0);
|
||||
+ preadv(fd, t, 2, 0);
|
||||
+ preadv(fd, iov, -1, 0);
|
||||
+ preadv(fd, iov, c, 0);
|
||||
+ preadv(fd, iov, 2, -5);
|
||||
+ preadv(-1, iov, 2, -5);
|
||||
+
|
||||
+ iov[1].iov_base = (void *) -1;
|
||||
+ pwritev(fd, iov, 2, 0);
|
||||
+ preadv(fd, iov, 2, 0);
|
||||
+ free(mem);
|
||||
+ } while (0);
|
||||
+
|
||||
+ close(fd);
|
||||
+ unlink("prwv_source");
|
||||
+ exit(EXIT_SUCCESS);
|
||||
+}
|
||||
diff --git a/memcheck/tests/linux/sys-preadv_pwritev.stderr.exp b/memcheck/tests/linux/sys-preadv_pwritev.stderr.exp
|
||||
new file mode 100644
|
||||
index 000000000..4fede44d8
|
||||
--- /dev/null
|
||||
+++ b/memcheck/tests/linux/sys-preadv_pwritev.stderr.exp
|
||||
@@ -0,0 +1,52 @@
|
||||
+Syscall param pwritev(vector) points to unaddressable byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv_pwritev.c:52)
|
||||
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
+
|
||||
+Syscall param pwritev(vector) points to unaddressable byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv_pwritev.c:53)
|
||||
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
+
|
||||
+Syscall param pwritev(vector) points to uninitialised byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv_pwritev.c:54)
|
||||
+ Address 0x........ is 0 bytes inside a block of size 16 alloc'd
|
||||
+ at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
+ by 0x........: main (sys-preadv_pwritev.c:48)
|
||||
+
|
||||
+Syscall param pwritev(count) contains uninitialised byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv_pwritev.c:56)
|
||||
+
|
||||
+Syscall param preadv(vector) points to unaddressable byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv_pwritev.c:60)
|
||||
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
+
|
||||
+Syscall param preadv(vector) points to unaddressable byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv_pwritev.c:61)
|
||||
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
+
|
||||
+Syscall param preadv(vector) points to uninitialised byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv_pwritev.c:62)
|
||||
+ Address 0x........ is 0 bytes inside a block of size 16 alloc'd
|
||||
+ at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
+ by 0x........: main (sys-preadv_pwritev.c:48)
|
||||
+
|
||||
+Syscall param preadv(count) contains uninitialised byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv_pwritev.c:64)
|
||||
+
|
||||
+Syscall param pwritev(vector[1]) points to unaddressable byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv_pwritev.c:69)
|
||||
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
+
|
||||
+Syscall param preadv(vector[1]) points to unaddressable byte(s)
|
||||
+ ...
|
||||
+ by 0x........: main (sys-preadv_pwritev.c:70)
|
||||
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
+
|
||||
diff --git a/memcheck/tests/linux/sys-preadv_pwritev.vgtest b/memcheck/tests/linux/sys-preadv_pwritev.vgtest
|
||||
new file mode 100644
|
||||
index 000000000..f07dc2935
|
||||
--- /dev/null
|
||||
+++ b/memcheck/tests/linux/sys-preadv_pwritev.vgtest
|
||||
@@ -0,0 +1,3 @@
|
||||
+prereq: test -e sys-preadv_pwritev
|
||||
+prog: sys-preadv_pwritev
|
||||
+vgopts: -q
|
||||
|
||||
commit 514f899388e05142513ff3f679a9e0131145e34e
|
||||
Author: Mark Wielaard <mark@klomp.org>
|
||||
Date: Wed Jul 3 10:27:17 2019 +0200
|
||||
|
||||
Hook up preadv2 and pwritev2 correctly for arm64.
|
||||
|
||||
Use the correct generic linux sys wrapper.
|
||||
|
||||
Followup for https://bugs.kde.org/408414
|
||||
|
||||
diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c
|
||||
index d12d40632..91329b682 100644
|
||||
--- a/coregrind/m_syswrap/syswrap-arm64-linux.c
|
||||
+++ b/coregrind/m_syswrap/syswrap-arm64-linux.c
|
||||
@@ -818,8 +818,8 @@ static SyscallTableEntry syscall_main_table[] = {
|
||||
LINX_(__NR_membarrier, sys_membarrier), // 283
|
||||
// (__NR_mlock2, sys_ni_syscall), // 284
|
||||
LINX_(__NR_copy_file_range, sys_copy_file_range), // 285
|
||||
- LINX_(__NR_preadv2, sys_ni_syscall), // 286
|
||||
- LINX_(__NR_pwritev2, sys_ni_syscall), // 287
|
||||
+ LINXY(__NR_preadv2, sys_preadv2), // 286
|
||||
+ LINX_(__NR_pwritev2, sys_pwritev2), // 287
|
||||
// (__NR_pkey_mprotect, sys_ni_syscall), // 288
|
||||
// (__NR_pkey_alloc, sys_ni_syscall), // 289
|
||||
// (__NR_pkey_free, sys_ni_syscall), // 290
|
153
SOURCES/valgrind-3.15.0-s390x-HRcVec128.patch
Normal file
153
SOURCES/valgrind-3.15.0-s390x-HRcVec128.patch
Normal file
@ -0,0 +1,153 @@
|
||||
From abbd80e7e23deb1f27fb50410c8b3a3f7cdfb646 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Arnez <arnez@linux.ibm.com>
|
||||
Date: Wed, 12 Feb 2020 14:13:55 +0100
|
||||
Subject: [PATCH] Bug 417452 - s390_insn_store_emit: dst->tag for HRcVec128
|
||||
|
||||
It was seen that the s390 instruction selector chose a wrong addressing
|
||||
mode for storing a vector register. The VST instruction only handles
|
||||
short (12-bit unsigned) displacements, but a long (20-bit signed)
|
||||
displacement was generated instead, resulting in a panic:
|
||||
|
||||
vex: the `impossible' happened:
|
||||
s390_insn_store_emit: unknown dst->tag for HRcVec128
|
||||
|
||||
The fix prevents long displacements for vector store operations. It also
|
||||
optimizes vector store operations from an Iex_Get, by converting them to a
|
||||
memory copy. This optimization was already performed for integer
|
||||
registers.
|
||||
---
|
||||
VEX/priv/host_s390_defs.c | 2 +-
|
||||
VEX/priv/host_s390_isel.c | 67 +++++++++++++++++++++++++++------------
|
||||
2 files changed, 48 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c
|
||||
index 9ad7240c4..47928cbe1 100644
|
||||
--- a/VEX/priv/host_s390_defs.c
|
||||
+++ b/VEX/priv/host_s390_defs.c
|
||||
@@ -6314,7 +6314,7 @@ s390_insn_memcpy(UChar size, s390_amode *dst, s390_amode *src)
|
||||
insn->variant.memcpy.src = src;
|
||||
insn->variant.memcpy.dst = dst;
|
||||
|
||||
- vassert(size == 1 || size == 2 || size == 4 || size == 8);
|
||||
+ vassert(size == 1 || size == 2 || size == 4 || size == 8 || size == 16);
|
||||
|
||||
return insn;
|
||||
}
|
||||
diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c
|
||||
index 97614c873..fff81fe0f 100644
|
||||
--- a/VEX/priv/host_s390_isel.c
|
||||
+++ b/VEX/priv/host_s390_isel.c
|
||||
@@ -302,12 +302,14 @@ ulong_fits_signed_8bit(ULong val)
|
||||
return val == v;
|
||||
}
|
||||
|
||||
-/* EXPR is an expression that is used as an address. Return an s390_amode
|
||||
- for it. If select_b12_b20_only is true the returned amode must be either
|
||||
- S390_AMODE_B12 or S390_AMODE_B20. */
|
||||
+/* EXPR is an expression that is used as an address. Return an s390_amode for
|
||||
+ it. If no_index is true the returned amode must be either S390_AMODE_B12 or
|
||||
+ S390_AMODE_B20. If short_displacement is true it must be either
|
||||
+ S390_AMODE_B12 or S390_AMODE_BX12. */
|
||||
static s390_amode *
|
||||
s390_isel_amode_wrk(ISelEnv *env, IRExpr *expr,
|
||||
- Bool select_b12_b20_only __attribute__((unused)))
|
||||
+ Bool no_index __attribute__((unused)),
|
||||
+ Bool short_displacement)
|
||||
{
|
||||
if (expr->tag == Iex_Binop && expr->Iex.Binop.op == Iop_Add64) {
|
||||
IRExpr *arg1 = expr->Iex.Binop.arg1;
|
||||
@@ -328,7 +330,7 @@ s390_isel_amode_wrk(ISelEnv *env, IRExpr *expr,
|
||||
if (ulong_fits_unsigned_12bit(value)) {
|
||||
return s390_amode_b12((Int)value, s390_isel_int_expr(env, arg1));
|
||||
}
|
||||
- if (ulong_fits_signed_20bit(value)) {
|
||||
+ if (!short_displacement && ulong_fits_signed_20bit(value)) {
|
||||
return s390_amode_b20((Int)value, s390_isel_int_expr(env, arg1));
|
||||
}
|
||||
}
|
||||
@@ -348,7 +350,25 @@ s390_isel_amode(ISelEnv *env, IRExpr *expr)
|
||||
/* Address computation should yield a 64-bit value */
|
||||
vassert(typeOfIRExpr(env->type_env, expr) == Ity_I64);
|
||||
|
||||
- am = s390_isel_amode_wrk(env, expr, /* B12, B20 only */ False);
|
||||
+ am = s390_isel_amode_wrk(env, expr, False, False);
|
||||
+
|
||||
+ /* Check post-condition */
|
||||
+ vassert(s390_amode_is_sane(am));
|
||||
+
|
||||
+ return am;
|
||||
+}
|
||||
+
|
||||
+/* Sometimes we need an amode with short (12-bit) displacement. An example is
|
||||
+ the vector-store opcode. */
|
||||
+static s390_amode *
|
||||
+s390_isel_amode_short(ISelEnv *env, IRExpr *expr)
|
||||
+{
|
||||
+ s390_amode *am;
|
||||
+
|
||||
+ /* Address computation should yield a 64-bit value */
|
||||
+ vassert(typeOfIRExpr(env->type_env, expr) == Ity_I64);
|
||||
+
|
||||
+ am = s390_isel_amode_wrk(env, expr, False, True);
|
||||
|
||||
/* Check post-condition */
|
||||
vassert(s390_amode_is_sane(am));
|
||||
@@ -379,7 +399,7 @@ s390_isel_amode_b12_b20(ISelEnv *env, IRExpr *expr)
|
||||
/* Address computation should yield a 64-bit value */
|
||||
vassert(typeOfIRExpr(env->type_env, expr) == Ity_I64);
|
||||
|
||||
- am = s390_isel_amode_wrk(env, expr, /* B12, B20 only */ True);
|
||||
+ am = s390_isel_amode_wrk(env, expr, True, False);
|
||||
|
||||
/* Check post-condition */
|
||||
vassert(s390_amode_is_sane(am) &&
|
||||
@@ -4727,7 +4747,26 @@ s390_isel_stmt(ISelEnv *env, IRStmt *stmt)
|
||||
|
||||
if (stmt->Ist.Store.end != Iend_BE) goto stmt_fail;
|
||||
|
||||
- am = s390_isel_amode(env, stmt->Ist.Store.addr);
|
||||
+ if (tyd == Ity_V128) {
|
||||
+ am = s390_isel_amode_short(env, stmt->Ist.Store.addr);
|
||||
+ } else {
|
||||
+ am = s390_isel_amode(env, stmt->Ist.Store.addr);
|
||||
+ }
|
||||
+
|
||||
+ /* Check whether we can use a memcpy. Currently, the restriction
|
||||
+ is that both amodes need to be B12, so MVC can be emitted.
|
||||
+ We do not consider a store whose data expression is a load because
|
||||
+ we don't want to deal with overlapping locations. */
|
||||
+ /* store(get) never overlaps*/
|
||||
+ if (am->tag == S390_AMODE_B12 &&
|
||||
+ stmt->Ist.Store.data->tag == Iex_Get) {
|
||||
+ UInt offset = stmt->Ist.Store.data->Iex.Get.offset;
|
||||
+ s390_amode *from = s390_amode_for_guest_state(offset);
|
||||
+ if (from->tag == S390_AMODE_B12) {
|
||||
+ addInstr(env, s390_insn_memcpy(sizeofIRType(tyd), am, from));
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
switch (tyd) {
|
||||
case Ity_I8:
|
||||
@@ -4742,18 +4781,6 @@ s390_isel_stmt(ISelEnv *env, IRStmt *stmt)
|
||||
addInstr(env, s390_insn_mimm(sizeofIRType(tyd), am, value));
|
||||
return;
|
||||
}
|
||||
- /* Check whether we can use a memcpy here. Currently, the restriction
|
||||
- is that both amodes need to be B12, so MVC can be emitted.
|
||||
- We do not consider a store whose data expression is a load because
|
||||
- we don't want to deal with overlapping locations. */
|
||||
- /* store(get) never overlaps*/
|
||||
- if (am->tag == S390_AMODE_B12 &&
|
||||
- stmt->Ist.Store.data->tag == Iex_Get) {
|
||||
- UInt offset = stmt->Ist.Store.data->Iex.Get.offset;
|
||||
- s390_amode *from = s390_amode_for_guest_state(offset);
|
||||
- addInstr(env, s390_insn_memcpy(sizeofIRType(tyd), am, from));
|
||||
- return;
|
||||
- }
|
||||
/* General case: compile data into a register */
|
||||
src = s390_isel_int_expr(env, stmt->Ist.Store.data);
|
||||
break;
|
||||
--
|
||||
2.23.0
|
||||
|
@ -3,7 +3,7 @@
|
||||
Summary: Tool for finding memory management bugs in programs
|
||||
Name: %{?scl_prefix}valgrind
|
||||
Version: 3.15.0
|
||||
Release: 9%{?dist}
|
||||
Release: 11%{?dist}
|
||||
Epoch: 1
|
||||
License: GPLv2+
|
||||
URL: http://www.valgrind.org/
|
||||
@ -125,6 +125,12 @@ Patch15: valgrind-3.15.0-avx-rdrand-f16c.patch
|
||||
# KDE#408091 Missing pkey syscalls
|
||||
Patch16: valgrind-3.15.0-pkey.patch
|
||||
|
||||
# KDE#408414 Add support for preadv2 and pwritev2 syscalls
|
||||
Patch17: valgrind-3.15.0-preadv2-pwritev2.patch
|
||||
|
||||
# KDE#417452 s390_insn_store_emit: dst->tag for HRcVec128
|
||||
Patch18: valgrind-3.15.0-s390x-HRcVec128.patch
|
||||
|
||||
BuildRequires: glibc-devel
|
||||
|
||||
%if %{build_openmpi}
|
||||
@ -275,6 +281,8 @@ Valgrind User Manual for details.
|
||||
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch18 -p1
|
||||
|
||||
%build
|
||||
|
||||
@ -495,6 +503,12 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Feb 14 2020 Mark Wielaard <mjw@redhat.com> - 3.15.0-11
|
||||
- Add valgrind-3.15.0-s390x-HRcVec128.patch
|
||||
|
||||
* Mon Aug 5 2019 Mark Wielaard <mjw@redhat.com> - 3.15.0-10
|
||||
- Add valgrind-3.15.0-preadv2-pwritev2.patch
|
||||
|
||||
* Wed May 29 2019 Mark Wielaard <mjw@redhat.com> - 3.15.0-9
|
||||
- Add valgrind-3.15.0-pkey.patch
|
||||
- Add valgrind-3.15.0-avx-rdrand-f16c.patch.
|
||||
|
Loading…
Reference in New Issue
Block a user