Skip to content

Commit

Permalink
Add implementation of memmove to avoid bugs in 32-bit glibc
Browse files Browse the repository at this point in the history
The memmove in glibc on 32-bit SSE2 systems, contained in
__memmove_sse2_unaligned, is buggy in at least versions
2.21 - 2.25 when crossing the 2GB boundary, so GAP must
include it's own simple memmove implementation.
  • Loading branch information
ChrisJefferson committed Feb 2, 2018
1 parent 79ce1d5 commit a2a9da9
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
50 changes: 50 additions & 0 deletions src/sysfiles.c
Original file line number Diff line number Diff line change
Expand Up @@ -3598,6 +3598,56 @@ Obj SyReadStringFid(Int fid) {
#endif


#ifdef SYS_IS_64_BIT
void * SyMemmove(void * dst, const void * src, UInt size)
{
return memmove(dst, src, size);
}
#else
// The memmove in glibc on 32-bit SSE2 systems, contained in
// __memmove_sse2_unaligned, is buggy in at least versions
// 2.21 - 2.25 when crossing the 2GB boundary, so GAP must
// include it's own simple memmove implementation.
void * SyMemmove(void * dst, const void * src, UInt size)
{
char * d = dst;
const char * s = src;

if ((dst == src) || (size == 0))
return dst;

if (d < s || d > s + size) {
memcpy(dst, src, size);
}
else {
d = d + (size - 1);
s = s + (size - 1);

// This is about 4x slower than glibc, but
// is simple and also complicated enough that
// gcc or clang seem unable to "optimise" it back
// into a call to memmove.

// Do size 4 jumps
while (size > 4) {
*d = *s;
*(d - 1) = *(s - 1);
*(d - 2) = *(s - 2);
*(d - 3) = *(s - 3);
d -= 4;
s -= 4;
size -= 4;
}
// Finish
while (size > 0) {
*d-- = *s--;
size--;
}
}
return dst;
}
#endif


/****************************************************************************
**
Expand Down
4 changes: 4 additions & 0 deletions src/sysfiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ extern Char * SyTmpname ( void );
*/
extern Char * SyTmpdir ( const Char * hint );


/****************************************************************************
**
*F void getwindowsize( void ) . probe the OS for the window size and
Expand Down Expand Up @@ -612,6 +613,9 @@ extern Obj SyReadStringFid(Int fid);
extern Obj SyReadStringFile(Int fid);
extern Obj SyReadStringFileGeneric(Int fid);

// Internal implementation of memmove, to avoid issues with glibc
void *SyMemmove(void *dst, const void* src, UInt size);

/****************************************************************************
**
*F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * *
Expand Down

0 comments on commit a2a9da9

Please sign in to comment.