161 lines
5.3 KiB
C
161 lines
5.3 KiB
C
/*
|
|
* Copyright (c) 2011 ARM Ltd
|
|
* 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. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. The name of the company may not be used to endorse or promote
|
|
* products derived from this software without specific prior written
|
|
* permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
|
|
#ifndef BUFF_SIZE
|
|
#define BUFF_SIZE 1024
|
|
#endif
|
|
|
|
#ifndef START_COPY
|
|
#define START_COPY 256
|
|
#endif
|
|
|
|
#ifndef MAX_BLOCK_SIZE
|
|
#define MAX_BLOCK_SIZE 128
|
|
#endif
|
|
|
|
#ifndef MAX_OFFSET
|
|
#define MAX_OFFSET 3
|
|
#endif
|
|
|
|
#if (START_COPY + MAX_OFFSET + MAX_BLOCK_SIZE >= BUFF_SIZE)
|
|
#error "Buffer overrun: START_COPY + MAX_OFFSET + MAX_BLOCK_SIZE >= BUFF_SIZE."
|
|
#endif
|
|
|
|
#define TOO_MANY_ERRORS 11
|
|
int errors = 0;
|
|
|
|
void
|
|
print_error (char const* msg, ...)
|
|
{
|
|
errors++;
|
|
if (errors == TOO_MANY_ERRORS)
|
|
{
|
|
fprintf (stderr, "Too many errors.\n");
|
|
}
|
|
else if (errors < TOO_MANY_ERRORS)
|
|
{
|
|
va_list ap;
|
|
va_start (ap, msg);
|
|
vfprintf (stderr, msg, ap);
|
|
va_end (ap);
|
|
}
|
|
else
|
|
{
|
|
/* Further errors omitted. */
|
|
}
|
|
}
|
|
|
|
int
|
|
main (void)
|
|
{
|
|
/* Allocate buffers to read and write from. */
|
|
char src[BUFF_SIZE], dest[BUFF_SIZE], backup_src[BUFF_SIZE];
|
|
|
|
/* Fill the source buffer with non-null values, reproducable random data. */
|
|
srand (1539);
|
|
int i, j;
|
|
unsigned sa;
|
|
unsigned da;
|
|
unsigned n;
|
|
for (i = 0; i < BUFF_SIZE; i++)
|
|
{
|
|
src[i] = (char)rand () | 1;
|
|
backup_src[i] = src[i];
|
|
}
|
|
|
|
/* Make calls to memcpy with block sizes ranging between 1 and
|
|
MAX_BLOCK_SIZE bytes, aligned and misaligned source and destination. */
|
|
for (sa = 0; sa <= MAX_OFFSET; sa++)
|
|
for (da = 0; da <= MAX_OFFSET; da++)
|
|
for (n = 1; n <= MAX_BLOCK_SIZE; n++)
|
|
{
|
|
printf (".");
|
|
/* Zero dest so we can check it properly after the copying. */
|
|
for (j = 0; j < BUFF_SIZE; j++)
|
|
dest[j] = 0;
|
|
|
|
void *ret = memcpy (dest + START_COPY + da, src + sa, n);
|
|
|
|
/* Check return value. */
|
|
if (ret != (dest + START_COPY + da))
|
|
print_error ("\nFailed: wrong return value in memcpy of %u bytes "
|
|
"with src_align %u and dst_align %u. "
|
|
"Return value and dest should be the same"
|
|
"(ret is %p, dest is %p)\n",
|
|
n, sa, da, ret, dest + START_COPY + da);
|
|
|
|
/* Check that content of the destination buffer
|
|
is the same as the source buffer, and
|
|
memory outside destination buffer is not modified. */
|
|
for (j = 0; j < BUFF_SIZE; j++)
|
|
if (j < START_COPY + da)
|
|
{
|
|
if (dest[j] != 0)
|
|
print_error ("\nFailed: after memcpy of %u bytes "
|
|
"with src_align %u and dst_align %u, "
|
|
"byte %u before the start of dest is not 0.\n",
|
|
n, sa, da, START_COPY - j);
|
|
}
|
|
else if (j < START_COPY + da + n)
|
|
{
|
|
i = j - START_COPY - da;
|
|
if (dest[j] != (src + sa)[i])
|
|
print_error ("\nFailed: after memcpy of %u bytes "
|
|
"with src_align %u and dst_align %u, "
|
|
"byte %u in dest and src are not the same.\n",
|
|
n, sa, da, i);
|
|
}
|
|
else if (dest[j] != 0)
|
|
{
|
|
print_error ("\nFailed: after memcpy of %u bytes "
|
|
"with src_align %u and dst_align %u, "
|
|
"byte %u after the end of dest is not 0.\n",
|
|
n, sa, da, j - START_COPY - da - n);
|
|
}
|
|
|
|
/* Check src is not modified. */
|
|
for (j = 0; j < BUFF_SIZE; j++)
|
|
if (src[i] != backup_src[i])
|
|
print_error ("\nFailed: after memcpy of %u bytes "
|
|
"with src_align %u and dst_align %u, "
|
|
"byte %u of src is modified.\n",
|
|
n, sa, da, j);
|
|
}
|
|
|
|
printf ("\n");
|
|
if (errors != 0)
|
|
abort ();
|
|
|
|
exit (0);
|
|
}
|