aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2012-05-11 17:59:23 -0400
committerChris Metcalf <cmetcalf@tilera.com>2012-05-14 15:46:12 -0400
commit575298fcd298bb3ff7d7ba0d0bceac9429ae2b5d (patch)
tree8c0ab53a454e65decce6edcc2bd64c4408feadb1
parentcbf92fc46644e084315e3fbe7e5ccb7cb499284e (diff)
downloadglibc-575298fcd298bb3ff7d7ba0d0bceac9429ae2b5d.tar.xz
glibc-575298fcd298bb3ff7d7ba0d0bceac9429ae2b5d.zip
tile: allow memcpy(p, p, n) without corrupting memory at "p"
Although this is not required by the definition of memcpy(), in practice this sort of thing does happen, and it's easy to make the code robust by doing nothing in this case. (Since structure copy causes the compiler to emit a memcpy, in the case where the target structure is the same as the destination, we were seeing corruption.)
-rw-r--r--ChangeLog.tile5
-rw-r--r--sysdeps/tile/tilegx/memcpy.c13
2 files changed, 17 insertions, 1 deletions
diff --git a/ChangeLog.tile b/ChangeLog.tile
index 5cdc293f8e..83136aa6c3 100644
--- a/ChangeLog.tile
+++ b/ChangeLog.tile
@@ -1,5 +1,10 @@
2012-05-12 Chris Metcalf <cmetcalf@tilera.com>
+ * sysdeps/tile/tilegx/memcpy.c: Allow memcpy(p, p, n)
+ without corrupting memory at "p".
+
+2012-05-12 Chris Metcalf <cmetcalf@tilera.com>
+
* sysdeps/tile/__tls_get_addr.S: Use __WORDSIZE, not _LP64.
2012-05-12 Chris Metcalf <cmetcalf@tilera.com>
diff --git a/sysdeps/tile/tilegx/memcpy.c b/sysdeps/tile/tilegx/memcpy.c
index 9cfb283c82..dd6e30dd60 100644
--- a/sysdeps/tile/tilegx/memcpy.c
+++ b/sysdeps/tile/tilegx/memcpy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011 Free Software Foundation, Inc.
+/* Copyright (C) 2011-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
@@ -107,6 +107,17 @@ __memcpy (void *__restrict dstv, const void *__restrict srcv, size_t n)
n -= sizeof (word_t))
*dst8++ = *src8++;
+ /* If copying to self, return. The test is cheap enough
+ that we do it despite the fact that the memcpy() contract
+ doesn't require us to support overlapping dst and src.
+ This is the most common case of overlap, and any close
+ overlap will cause corruption due to the wh64 below.
+ This case is particularly important since the compiler
+ will emit memcpy() calls for aggregate copies even if it
+ can't prove that src != dst. */
+ if (__builtin_expect (dst8 == src8, 0))
+ return dstv;
+
for (; n >= CHIP_L2_LINE_SIZE ();)
{
__insn_wh64 (dst8);