2 changed files with 188 additions and 0 deletions
@ -0,0 +1,184 @@ |
|||
/* A minor test-program for memmove.
|
|||
Copyright (C) 2005 Axis Communications. |
|||
All rights reserved. |
|||
|
|||
Redistribution and use in source and binary forms, with or without |
|||
modification, are permitted provided that the following conditions |
|||
are met: |
|||
|
|||
1. Redistributions of source code must retain the above copyright |
|||
notice, this list of conditions and the following disclaimer. |
|||
|
|||
2. Neither the name of Axis Communications nor the names of its |
|||
contributors may be used to endorse or promote products derived |
|||
from this software without specific prior written permission. |
|||
|
|||
THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS |
|||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS |
|||
COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
|||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
|||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
|||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
POSSIBILITY OF SUCH DAMAGE. */ |
|||
|
|||
/* Test moves of 0..MAX bytes; overlapping-src-higher,
|
|||
overlapping-src-lower and non-overlapping. The overlap varies with |
|||
1..N where N is the size moved. This means an order of MAX**2 |
|||
iterations. The size of an octet may seem appropriate for MAX and |
|||
makes an upper limit for simple testing. For the CRIS simulator, |
|||
making this 256 added 90s to the test-run (2GHz P4) while 64 (4s) was |
|||
enough to spot the bugs that had crept in, hence the number chosen. */ |
|||
#define MAX 64 |
|||
|
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
|
|||
#define TOO_MANY_ERRORS 11 |
|||
int errors = 0; |
|||
|
|||
#define DEBUGP \ |
|||
if (errors == TOO_MANY_ERRORS) \ |
|||
printf ("Further errors omitted\n"); \ |
|||
else if (errors < TOO_MANY_ERRORS) \ |
|||
printf |
|||
|
|||
/* A safe target-independent memmove. */ |
|||
|
|||
void |
|||
mymemmove (unsigned char *dest, unsigned char *src, size_t n) |
|||
{ |
|||
size_t i; |
|||
|
|||
if ((src <= dest && src + n <= dest) |
|||
|| src >= dest) |
|||
while (n-- > 0) |
|||
*dest++ = *src++; |
|||
else |
|||
{ |
|||
dest += n; |
|||
src += n; |
|||
while (n-- > 0) |
|||
*--dest = *--src; |
|||
} |
|||
} |
|||
|
|||
/* It's either the noinline attribute or forcing the test framework to
|
|||
pass -fno-builtin-memmove. */ |
|||
void |
|||
xmemmove (unsigned char *dest, unsigned char *src, size_t n) |
|||
__attribute__ ((__noinline__)); |
|||
|
|||
void |
|||
xmemmove (unsigned char *dest, unsigned char *src, size_t n) |
|||
{ |
|||
void *retp; |
|||
retp = memmove (dest, src, n); |
|||
|
|||
if (retp != dest) |
|||
{ |
|||
errors++; |
|||
DEBUGP ("memmove of n bytes returned %p instead of dest=%p\n", |
|||
retp, dest); |
|||
} |
|||
} |
|||
|
|||
|
|||
/* Fill the array with something we can associate with a position, but
|
|||
not exactly the same as the position index. */ |
|||
|
|||
void |
|||
fill (unsigned char dest[MAX*3]) |
|||
{ |
|||
size_t i; |
|||
for (i = 0; i < MAX*3; i++) |
|||
dest[i] = (10 + i) % MAX; |
|||
} |
|||
|
|||
int |
|||
main (void) |
|||
{ |
|||
size_t i; |
|||
int errors = 0; |
|||
|
|||
/* Leave some room before and after the area tested, so we can detect
|
|||
overwrites of up to N bytes, N being the amount tested. If you |
|||
want to test using valgrind, make these malloced instead. */ |
|||
unsigned char from_test[MAX*3]; |
|||
unsigned char to_test[MAX*3]; |
|||
unsigned char from_known[MAX*3]; |
|||
unsigned char to_known[MAX*3]; |
|||
|
|||
/* Non-overlap. */ |
|||
for (i = 0; i < MAX; i++) |
|||
{ |
|||
/* Do the memmove first before setting the known array, so we know
|
|||
it didn't change any of the known array. */ |
|||
fill (from_test); |
|||
fill (to_test); |
|||
xmemmove (to_test + MAX, 1 + from_test + MAX, i); |
|||
|
|||
fill (from_known); |
|||
fill (to_known); |
|||
mymemmove (to_known + MAX, 1 + from_known + MAX, i); |
|||
|
|||
if (memcmp (to_known, to_test, sizeof (to_known)) != 0) |
|||
{ |
|||
errors++; |
|||
DEBUGP ("memmove failed non-overlap test for %d bytes\n", i); |
|||
} |
|||
} |
|||
|
|||
/* Overlap-from-before. */ |
|||
for (i = 0; i < MAX; i++) |
|||
{ |
|||
size_t j; |
|||
for (j = 0; j < i; j++) |
|||
{ |
|||
fill (to_test); |
|||
xmemmove (to_test + MAX * 2 - i, to_test + MAX * 2 - i - j, i); |
|||
|
|||
fill (to_known); |
|||
mymemmove (to_known + MAX * 2 - i, to_known + MAX * 2 - i - j, i); |
|||
|
|||
if (memcmp (to_known, to_test, sizeof (to_known)) != 0) |
|||
{ |
|||
errors++; |
|||
DEBUGP ("memmove failed for %d bytes," |
|||
" with src %d bytes before dest\n", |
|||
i, j); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* Overlap-from-after. */ |
|||
for (i = 0; i < MAX; i++) |
|||
{ |
|||
size_t j; |
|||
for (j = 0; j < i; j++) |
|||
{ |
|||
fill (to_test); |
|||
xmemmove (to_test + MAX, to_test + MAX + j, i); |
|||
|
|||
fill (to_known); |
|||
mymemmove (to_known + MAX, to_known + MAX + j, i); |
|||
|
|||
if (memcmp (to_known, to_test, sizeof (to_known)) != 0) |
|||
{ |
|||
errors++; |
|||
DEBUGP ("memmove failed when moving %d bytes," |
|||
" with src %d bytes after dest\n", |
|||
i, j); |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (errors != 0) |
|||
abort (); |
|||
exit (0); |
|||
} |
|||
Loading…
Reference in new issue