1 /* The z13 stpcpy implementation plays some alignment tricks for good
2 performance. This test tries to make sure it works correctly and
3 does not access bytes beyond the source and destination
4 strings. */
5
6 /* { dg-do run } */
7 /* { dg-require-effective-target s390_vx } */
8 /* { dg-options "-O3 -mzarch -march=z13" } */
9
10 #include <stdio.h>
11 #include <sys/mman.h>
12
13 #define PAGE_SIZE 4096
14
15 struct {
16 char unused[PAGE_SIZE - 32];
17 char m32[15]; /* page bndry - 32 */
18 char m17[1];
19 char m16[1];
20 char m15[14];
21 char m1[1];
22 char next_page[PAGE_SIZE];
23 } s, d __attribute__((aligned(PAGE_SIZE)));
24
25 char *__attribute__((noinline))
my_stpcpy(char * dest,const char * src)26 my_stpcpy(char *dest, const char *src)
27 {
28 return __builtin_stpcpy (dest, src);
29 }
30
31 void __attribute__ ((noinline))
check(char * dest,char * src,size_t len)32 check (char *dest, char *src, size_t len)
33 {
34 char *result;
35
36 result = my_stpcpy (dest, src);
37 if (result != dest + len)
38 __builtin_abort ();
39 if (__builtin_memcmp (src, dest, len) != 0)
40 __builtin_abort ();
41 }
42
43 int
main()44 main ()
45 {
46 char *src[5] = { s.m32, s.m17, s.m16, s.m15, s.m1 };
47 char *dst[5] = { d.m32, d.m17, d.m16, d.m15, d.m1 };
48 int len[8] = { 33, 32, 31, 17, 16, 15, 1, 0 };
49 int i, j, k;
50 char backup;
51
52 for (i = 0; i < sizeof (s); i++)
53 ((char*)&s)[i] = i % 26 + 97;
54
55 for (i = 0; i < 5; i++)
56 for (j = 0; j < 5; j++)
57 for (k = 0; k < 8; k++)
58 {
59 backup = src[j][len[k]];
60 src[j][len[k]] = 0;
61 __builtin_memset (&d, 0, sizeof (d));
62 check (dst[i], src[j], len[k]);
63 src[j][len[k]] = backup;
64 }
65
66 /* Make all source strings end before the page boundary. */
67 backup = s.m1[0];
68 s.m1[0] = 0;
69
70 if (mprotect (&s.next_page, PAGE_SIZE, PROT_NONE) == -1)
71 perror ("mprotect src");
72
73 for (i = 0; i < 5; i++)
74 for (j = 0; j < 5; j++)
75 check (dst[i], src[j],
76 PAGE_SIZE - ((unsigned long)src[j] & ((1UL << 12) - 1)) - 1);
77
78 if (mprotect (&s.next_page, PAGE_SIZE, PROT_READ | PROT_WRITE) == -1)
79 perror ("mprotect src");
80
81 s.m1[0] = backup;
82
83 if (mprotect (&d.next_page, PAGE_SIZE, PROT_NONE) == -1)
84 perror ("mprotect dst");
85
86 for (i = 0; i < 5; i++)
87 for (j = 0; j < 5; j++)
88 {
89 int len = PAGE_SIZE - ((unsigned long)dst[i] & ((1UL << 12) - 1)) - 1;
90 char backup = src[j][len];
91
92 src[j][len] = 0;
93 __builtin_memset (&d, 0,
94 (unsigned long)&d.next_page - (unsigned long)&d);
95 check (dst[i], src[j], len);
96 src[j][len] = backup;
97 }
98
99 return 0;
100 }
101