xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.arch/sparc64-adi.c (revision 782713e6c126f1866c6d9cfdee4ceb49483b5828)
1 /* Application Data Integrity (ADI) test in sparc64.
2 
3    Copyright 2017-2020 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <pthread.h>
24 #include <sys/types.h>
25 #include <sys/wait.h>
26 #include <unistd.h>
27 #include <sys/errno.h>
28 #include <sys/utsname.h>
29 #include <sys/param.h>
30 #include <malloc.h>
31 #include <string.h>
32 #include <signal.h>
33 #include <sys/shm.h>
34 #include <errno.h>
35 #include <sys/mman.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <poll.h>
39 #include <setjmp.h>
40 #include "adi.h"
41 
42 #define	ONEKB		1024
43 #define PAT 		0xdeadbeaf
44 
45 #define MAPSIZE 8192
46 #define SHMSIZE 102400
47 #ifndef PROT_ADI
48 #define PROT_ADI 0x10
49 #endif
50 
51 static int
52 memory_fill (char *addr, size_t size, int pattern)
53 {
54   long *aligned_addr = (long *) addr;
55   long i;
56   for (i = 0; i < size / sizeof (long); i += ONEKB)
57     {
58       *aligned_addr = pattern;
59       aligned_addr = aligned_addr + ONEKB;
60     }
61   return (0);
62 }
63 
64 int main ()
65 {
66   char *haddr;
67   caddr_t vaddr;
68   int	version;
69 
70   /* Test ISM. */
71   int shmid = shmget (IPC_PRIVATE, SHMSIZE, IPC_CREAT | 0666);
72   if (shmid == -1)
73     exit(1);
74   char *shmaddr = (char *)shmat (shmid, NULL, 0x666 | SHM_RND);
75   if (shmaddr == (char *)-1)
76     {
77       shmctl (shmid, IPC_RMID, NULL);
78       exit(1);
79     }
80   /* Enable ADI on ISM segment. */
81   if (mprotect (shmaddr, SHMSIZE, PROT_READ|PROT_WRITE|PROT_ADI))
82     {
83       perror ("mprotect failed");
84       goto err_out;
85     }
86   if (memory_fill (shmaddr, SHMSIZE, PAT) != 0) /* line breakpoint here */
87     {
88       exit(1);
89     }
90   adi_clr_version (shmaddr, SHMSIZE);
91   caddr_t vshmaddr = adi_set_version (shmaddr, SHMSIZE, 0x8);
92   if (vshmaddr == 0)
93     exit(1);
94   /* Test mmap. */
95   int fd = open ("/dev/zero", O_RDWR);
96   if (fd < 0)
97     exit(1);
98   char *maddr = (char *)mmap (NULL, MAPSIZE, PROT_READ|PROT_WRITE,
99                               MAP_PRIVATE, fd, 0);
100   if (maddr == (char *)-1)
101     exit(1);
102   /* Enable ADI. */
103   if (mprotect (shmaddr, MAPSIZE, PROT_READ|PROT_WRITE|PROT_ADI))
104     {
105       perror ("mprotect failed");
106       goto err_out;
107 
108     }
109   if (memory_fill (maddr, MAPSIZE, PAT) != 0)
110     exit(1);
111   caddr_t vmaddr = adi_set_version (maddr, MAPSIZE, 0x8);
112 
113   /* Test heap. */
114   haddr = (char*) memalign (MAPSIZE, MAPSIZE);
115   /* Enable ADI. */
116   if (mprotect (shmaddr, MAPSIZE, PROT_READ|PROT_WRITE|PROT_ADI))
117     {
118       perror ("mprotect failed");
119       goto err_out;
120     }
121 
122   if (memory_fill (haddr, MAPSIZE, PAT) != 0)
123     exit(1);
124   adi_clr_version (haddr, MAPSIZE);
125   /* Set some ADP version number. */
126   caddr_t vaddr1, vaddr2, vaddr3, vaddr4;
127   vaddr = adi_set_version (haddr, 64*2, 0x8);
128   vaddr1 = adi_set_version (haddr+64*2, 64*2, 0x9);
129   vaddr2 = adi_clr_version (haddr+64*4, 64*2);
130   vaddr3 = adi_set_version (haddr+64*6, 64*2, 0xa);
131   vaddr4 = adi_set_version (haddr+64*8, 64*10, 0x3);
132   if (vaddr == 0)
133     exit(1);
134   char *versioned_p = vaddr;
135   *versioned_p = 'a';
136   char *uvp = haddr;	// unversioned pointer
137   *uvp = 'b';		// version mismatch trap
138 
139   return (0);
140 err_out:
141   if (shmdt ((const void *)shmaddr) != 0)
142     perror ("Detach failure");
143   shmctl (shmid, IPC_RMID, NULL);
144   exit (1);
145 }
146