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 vector } */ 8/* { dg-options "-O3 -mzarch -march=z13" } */ 9 10#include <stdio.h> 11#include <sys/mman.h> 12 13#define PAGE_SIZE 4096 14 15struct { 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 25char *__attribute__((noinline)) 26my_stpcpy(char *dest, const char *src) 27{ 28 return __builtin_stpcpy (dest, src); 29} 30 31void __attribute__ ((noinline)) 32check (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 43int 44main () 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