/* * 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 #include #include #include #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); }