summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Krause <minipli@googlemail.com>2012-03-31 17:23:53 +0200
committerPeter Stuge <peter@stuge.se>2012-03-31 20:26:20 +0200
commitdd30acdd590f6a39a5d3c4a38e3d949e73b5e2fa (patch)
tree143a53d3981b74f78ac3759a0fc3d3949c923d53
parent819c7d4a35b7b11a832d8e52d34b6f5b32e24cc4 (diff)
Fix issues with x86 memcpy
The x86 memcpy() implementation did not mention its implicit output registers ESI, EDI and ECX which might make this code miscompile when the compiler uses the value of EDI for the return value *after* the 'rep movsb' has completed. That would break the API of memcpy as this would return 'dst+len' instead of 'dst'. Fix this possible bug by removing the wrong comment and listing all output registers as such (using dummy stack variables that get optimized away). Also the leading 'cld' is superflous as the ABI mandates the direction flag to be cleared all the time when we're in C (see <http://gcc.gnu.org/gcc-4.3/changes.html>) and we have no ASM call sites that might require it to be cleared explicitly (SMM might come to mind, but it clears the DF itself before passing control to the C part of the SMI handler). Last but not least fix the prototype to match the one from <string.h>. Change-Id: I106422d41180c4ed876078cabb26b45e49f3fa93 Signed-off-by: Mathias Krause <minipli@googlemail.com> Reviewed-on: http://review.coreboot.org/836 Tested-by: build bot (Jenkins) Reviewed-by: Peter Stuge <peter@stuge.se>
-rw-r--r--src/arch/x86/lib/memcpy.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/src/arch/x86/lib/memcpy.c b/src/arch/x86/lib/memcpy.c
index de210928a3..f8607cfc50 100644
--- a/src/arch/x86/lib/memcpy.c
+++ b/src/arch/x86/lib/memcpy.c
@@ -1,13 +1,15 @@
#include <string.h>
-void *memcpy(void *__restrict __dest,
- __const void *__restrict __src, size_t __n)
+void *memcpy(void *dest, const void *src, size_t n)
{
- asm("cld\n"
- "rep\n"
- "movsb"
- : /* no input (?) */
- :"S"(__src), "D"(__dest), "c"(__n)
- );
- return __dest;
+ unsigned long d0, d1, d2;
+
+ asm volatile(
+ "rep movsb"
+ : "=S"(d0), "=D"(d1), "=c"(d2)
+ : "0"(src), "1"(dest), "2"(n)
+ : "memory"
+ );
+
+ return dest;
}