base: fix memmove implementation
Also make 'memcpy' to behave like memmove on region overlap. Issue #604
This commit is contained in:
parent
e8c063a8b4
commit
1a30bac3ea
|
@ -49,6 +49,29 @@ namespace Genode {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple memmove
|
||||||
|
*
|
||||||
|
* \param dst destination memory block
|
||||||
|
* \param src source memory block
|
||||||
|
* \param size number of bytes to move
|
||||||
|
*
|
||||||
|
* \return pointer to destination memory block
|
||||||
|
*/
|
||||||
|
inline void *memmove(void *dst, const void *src, size_t size)
|
||||||
|
{
|
||||||
|
char *d = (char *)dst, *s = (char *)src;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (s > d)
|
||||||
|
for (i = 0; i < size; i++, *d++ = *s++);
|
||||||
|
else
|
||||||
|
for (s += size - 1, d += size - 1, i = size; i-- > 0; *d-- = *s--);
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy memory block
|
* Copy memory block
|
||||||
*
|
*
|
||||||
|
@ -63,6 +86,10 @@ namespace Genode {
|
||||||
char *d = (char *)dst, *s = (char *)src;
|
char *d = (char *)dst, *s = (char *)src;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
/* check for overlap */
|
||||||
|
if ((d + size > s) && (s + size > d))
|
||||||
|
return memmove(dst, src, size);
|
||||||
|
|
||||||
/* try cpu specific version first */
|
/* try cpu specific version first */
|
||||||
if ((i = size - memcpy_cpu(dst, src, size)) == size)
|
if ((i = size - memcpy_cpu(dst, src, size)) == size)
|
||||||
return dst;
|
return dst;
|
||||||
|
@ -86,13 +113,6 @@ namespace Genode {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Memmove wrapper for sophisticated overlapping-aware memcpy
|
|
||||||
*/
|
|
||||||
inline void *memmove(void *dst, const void *src, size_t size) {
|
|
||||||
return memcpy(dst, src, size); }
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy string
|
* Copy string
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue
Block a user