xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/powerpc/copyloops/validate.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun #include <malloc.h>
3*4882a593Smuzhiyun #include <string.h>
4*4882a593Smuzhiyun #include <stdlib.h>
5*4882a593Smuzhiyun #include <stdbool.h>
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include "utils.h"
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #define MAX_LEN 8192
10*4882a593Smuzhiyun #define MAX_OFFSET 16
11*4882a593Smuzhiyun #define MIN_REDZONE 128
12*4882a593Smuzhiyun #define BUFLEN (MAX_LEN+MAX_OFFSET+2*MIN_REDZONE)
13*4882a593Smuzhiyun #define POISON 0xa5
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun unsigned long COPY_LOOP(void *to, const void *from, unsigned long size);
16*4882a593Smuzhiyun 
do_one(char * src,char * dst,unsigned long src_off,unsigned long dst_off,unsigned long len,void * redzone,void * fill)17*4882a593Smuzhiyun static void do_one(char *src, char *dst, unsigned long src_off,
18*4882a593Smuzhiyun 		   unsigned long dst_off, unsigned long len, void *redzone,
19*4882a593Smuzhiyun 		   void *fill)
20*4882a593Smuzhiyun {
21*4882a593Smuzhiyun 	char *srcp, *dstp;
22*4882a593Smuzhiyun 	unsigned long ret;
23*4882a593Smuzhiyun 	unsigned long i;
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun 	srcp = src + MIN_REDZONE + src_off;
26*4882a593Smuzhiyun 	dstp = dst + MIN_REDZONE + dst_off;
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	memset(src, POISON, BUFLEN);
29*4882a593Smuzhiyun 	memset(dst, POISON, BUFLEN);
30*4882a593Smuzhiyun 	memcpy(srcp, fill, len);
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	ret = COPY_LOOP(dstp, srcp, len);
33*4882a593Smuzhiyun 	if (ret && ret != (unsigned long)dstp) {
34*4882a593Smuzhiyun 		printf("(%p,%p,%ld) returned %ld\n", dstp, srcp, len, ret);
35*4882a593Smuzhiyun 		abort();
36*4882a593Smuzhiyun 	}
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 	if (memcmp(dstp, srcp, len)) {
39*4882a593Smuzhiyun 		printf("(%p,%p,%ld) miscompare\n", dstp, srcp, len);
40*4882a593Smuzhiyun 		printf("src: ");
41*4882a593Smuzhiyun 		for (i = 0; i < len; i++)
42*4882a593Smuzhiyun 			printf("%02x ", srcp[i]);
43*4882a593Smuzhiyun 		printf("\ndst: ");
44*4882a593Smuzhiyun 		for (i = 0; i < len; i++)
45*4882a593Smuzhiyun 			printf("%02x ", dstp[i]);
46*4882a593Smuzhiyun 		printf("\n");
47*4882a593Smuzhiyun 		abort();
48*4882a593Smuzhiyun 	}
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	if (memcmp(dst, redzone, dstp - dst)) {
51*4882a593Smuzhiyun 		printf("(%p,%p,%ld) redzone before corrupted\n",
52*4882a593Smuzhiyun 		       dstp, srcp, len);
53*4882a593Smuzhiyun 		abort();
54*4882a593Smuzhiyun 	}
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	if (memcmp(dstp+len, redzone, dst+BUFLEN-(dstp+len))) {
57*4882a593Smuzhiyun 		printf("(%p,%p,%ld) redzone after corrupted\n",
58*4882a593Smuzhiyun 		       dstp, srcp, len);
59*4882a593Smuzhiyun 		abort();
60*4882a593Smuzhiyun 	}
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun 
test_copy_loop(void)63*4882a593Smuzhiyun int test_copy_loop(void)
64*4882a593Smuzhiyun {
65*4882a593Smuzhiyun 	char *src, *dst, *redzone, *fill;
66*4882a593Smuzhiyun 	unsigned long len, src_off, dst_off;
67*4882a593Smuzhiyun 	unsigned long i;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	src = memalign(BUFLEN, BUFLEN);
70*4882a593Smuzhiyun 	dst = memalign(BUFLEN, BUFLEN);
71*4882a593Smuzhiyun 	redzone = malloc(BUFLEN);
72*4882a593Smuzhiyun 	fill = malloc(BUFLEN);
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	if (!src || !dst || !redzone || !fill) {
75*4882a593Smuzhiyun 		fprintf(stderr, "malloc failed\n");
76*4882a593Smuzhiyun 		exit(1);
77*4882a593Smuzhiyun 	}
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	memset(redzone, POISON, BUFLEN);
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	/* Fill with sequential bytes */
82*4882a593Smuzhiyun 	for (i = 0; i < BUFLEN; i++)
83*4882a593Smuzhiyun 		fill[i] = i & 0xff;
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	for (len = 1; len < MAX_LEN; len++) {
86*4882a593Smuzhiyun 		for (src_off = 0; src_off < MAX_OFFSET; src_off++) {
87*4882a593Smuzhiyun 			for (dst_off = 0; dst_off < MAX_OFFSET; dst_off++) {
88*4882a593Smuzhiyun 				do_one(src, dst, src_off, dst_off, len,
89*4882a593Smuzhiyun 				       redzone, fill);
90*4882a593Smuzhiyun 			}
91*4882a593Smuzhiyun 		}
92*4882a593Smuzhiyun 	}
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	return 0;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun 
main(void)97*4882a593Smuzhiyun int main(void)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun 	return test_harness(test_copy_loop, str(COPY_LOOP));
100*4882a593Smuzhiyun }
101