diff options
Diffstat (limited to 'gdb/testsuite/gdb.arch/sparc64-adi.c')
-rw-r--r-- | gdb/testsuite/gdb.arch/sparc64-adi.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.arch/sparc64-adi.c b/gdb/testsuite/gdb.arch/sparc64-adi.c new file mode 100644 index 0000000..704fe26 --- /dev/null +++ b/gdb/testsuite/gdb.arch/sparc64-adi.c @@ -0,0 +1,145 @@ +/* Application Data Integrity (ADI) test in sparc64. + + Copyright 2017 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <pthread.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <sys/errno.h> +#include <sys/utsname.h> +#include <sys/param.h> +#include <malloc.h> +#include <string.h> +#include <signal.h> +#include <sys/shm.h> +#include <errno.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <poll.h> +#include <setjmp.h> +#include "adi.h" + +#define ONEKB 1024 +#define PAT 0xdeadbeaf + +#define MAPSIZE 8192 +#define SHMSIZE 102400 +#ifndef PROT_ADI +#define PROT_ADI 0x10 +#endif + +static int +memory_fill (char *addr, size_t size, int pattern) +{ + long *aligned_addr = (long *) addr; + long i; + for (i = 0; i < size / sizeof (long); i += ONEKB) + { + *aligned_addr = pattern; + aligned_addr = aligned_addr + ONEKB; + } + return (0); +} + +int main () +{ + char *haddr; + caddr_t vaddr; + int version; + + /* Test ISM. */ + int shmid = shmget (IPC_PRIVATE, SHMSIZE, IPC_CREAT | 0666); + if (shmid == -1) + exit(1); + char *shmaddr = (char *)shmat (shmid, NULL, 0x666 | SHM_RND); + if (shmaddr == (char *)-1) + { + shmctl (shmid, IPC_RMID, NULL); + exit(1); + } + /* Enable ADI on ISM segment. */ + if (mprotect (shmaddr, SHMSIZE, PROT_READ|PROT_WRITE|PROT_ADI)) + { + perror ("mprotect failed"); + goto err_out; + } + if (memory_fill (shmaddr, SHMSIZE, PAT) != 0) /* line breakpoint here */ + { + exit(1); + } + adi_clr_version (shmaddr, SHMSIZE); + caddr_t vshmaddr = adi_set_version (shmaddr, SHMSIZE, 0x8); + if (vshmaddr == 0) + exit(1); + /* Test mmap. */ + int fd = open ("/dev/zero", O_RDWR); + if (fd < 0) + exit(1); + char *maddr = (char *)mmap (NULL, MAPSIZE, PROT_READ|PROT_WRITE, + MAP_PRIVATE, fd, 0); + if (maddr == (char *)-1) + exit(1); + /* Enable ADI. */ + if (mprotect (shmaddr, MAPSIZE, PROT_READ|PROT_WRITE|PROT_ADI)) + { + perror ("mprotect failed"); + goto err_out; + + } + if (memory_fill (maddr, MAPSIZE, PAT) != 0) + exit(1); + caddr_t vmaddr = adi_set_version (maddr, MAPSIZE, 0x8); + + /* Test heap. */ + haddr = (char*) memalign (MAPSIZE, MAPSIZE); + /* Enable ADI. */ + if (mprotect (shmaddr, MAPSIZE, PROT_READ|PROT_WRITE|PROT_ADI)) + { + perror ("mprotect failed"); + goto err_out; + } + + if (memory_fill (haddr, MAPSIZE, PAT) != 0) + exit(1); + adi_clr_version (haddr, MAPSIZE); + /* Set some ADP version number. */ + caddr_t vaddr1, vaddr2, vaddr3, vaddr4; + vaddr = adi_set_version (haddr, 64*2, 0x8); + vaddr1 = adi_set_version (haddr+64*2, 64*2, 0x9); + vaddr2 = adi_clr_version (haddr+64*4, 64*2); + vaddr3 = adi_set_version (haddr+64*6, 64*2, 0xa); + vaddr4 = adi_set_version (haddr+64*8, 64*10, 0x3); + if (vaddr == 0) + exit(1); + char *versioned_p = vaddr; + *versioned_p = 'a'; + char *uvp = haddr; // unversioned pointer + *uvp = 'b'; // version mismatch trap + + return (0); +err_out: + if (shmdt ((const void *)shmaddr) != 0) + perror ("Detach failure"); + shmctl (shmid, IPC_RMID, NULL); + exit (1); +} |