From dd28bebd024b4c7cfb6352126cd010d389a8d374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 5 Apr 2018 15:03:22 +0100 Subject: tests/tcg: move architecture independent tests into subdir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will want to build these for all supported guest architectures so lets move them all into one place. We also drop test_path at this point because it needs qemu utils and glib bits which is hard to support for cross compiling. Signed-off-by: Alex Bennée Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson --- MAINTAINERS | 4 + tests/tcg/Makefile | 31 --- tests/tcg/README | 10 +- tests/tcg/linux-test.c | 539 ------------------------------------ tests/tcg/multiarch/Makefile.target | 36 +++ tests/tcg/multiarch/README | 1 + tests/tcg/multiarch/linux-test.c | 539 ++++++++++++++++++++++++++++++++++++ tests/tcg/multiarch/sha1.c | 240 ++++++++++++++++ tests/tcg/multiarch/test-mmap.c | 484 ++++++++++++++++++++++++++++++++ tests/tcg/multiarch/testthread.c | 57 ++++ tests/tcg/sha1.c | 240 ---------------- tests/tcg/test-mmap.c | 484 -------------------------------- tests/tcg/test_path.c | 157 ----------- tests/tcg/testthread.c | 57 ---- 14 files changed, 1365 insertions(+), 1514 deletions(-) delete mode 100644 tests/tcg/linux-test.c create mode 100644 tests/tcg/multiarch/Makefile.target create mode 100644 tests/tcg/multiarch/README create mode 100644 tests/tcg/multiarch/linux-test.c create mode 100644 tests/tcg/multiarch/sha1.c create mode 100644 tests/tcg/multiarch/test-mmap.c create mode 100644 tests/tcg/multiarch/testthread.c delete mode 100644 tests/tcg/sha1.c delete mode 100644 tests/tcg/test-mmap.c delete mode 100644 tests/tcg/test_path.c delete mode 100644 tests/tcg/testthread.c diff --git a/MAINTAINERS b/MAINTAINERS index da91501..28dc787 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -303,6 +303,10 @@ F: target/tricore/ F: hw/tricore/ F: include/hw/tricore/ +Multiarch Linux User Tests +M: Alex Bennée +F: tests/tcg/multiarch/ + Guest CPU Cores (KVM): ---------------------- diff --git a/tests/tcg/Makefile b/tests/tcg/Makefile index 89e3342..e123951 100644 --- a/tests/tcg/Makefile +++ b/tests/tcg/Makefile @@ -18,12 +18,9 @@ LDFLAGS= # also, pi_10.com runs indefinitely I386_TESTS=hello-i386 \ - linux-test \ - testthread \ sha1-i386 \ test-i386 \ test-i386-fprem \ - test-mmap \ # runcom # native i386 compilers sometimes are not biarch. assume cross-compilers are @@ -47,8 +44,6 @@ run-%: % -$(QEMU) ./$* run-hello-i386: hello-i386 -run-linux-test: linux-test -run-testthread: testthread run-sha1-i386: sha1-i386 run-test-i386: test-i386 @@ -66,11 +61,6 @@ run-test-x86_64: test-x86_64 -$(QEMU_X86_64) test-x86_64 > test-x86_64.out @if diff -u test-x86_64.ref test-x86_64.out ; then echo "Auto Test OK"; fi -run-test-mmap: test-mmap - -$(QEMU) ./test-mmap - -$(QEMU) -p 8192 ./test-mmap 8192 - -$(QEMU) -p 16384 ./test-mmap 16384 - -$(QEMU) -p 32768 ./test-mmap 32768 run-runcom: runcom -$(QEMU) ./runcom $(SRC_PATH)/tests/pi_10.com @@ -80,17 +70,10 @@ run-test_path: test_path # rules to compile tests -test_path: test_path.o - -test_path.o: test_path.c - hello-i386: hello-i386.c $(CC_I386) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $< strip $@ -testthread: testthread.c - $(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread - # i386/x86_64 emulation test (test various opcodes) */ test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \ test-i386.h test-i386-shift.h test-i386-muldiv.h @@ -104,28 +87,14 @@ test-x86_64: test-i386.c \ test-i386.h test-i386-shift.h test-i386-muldiv.h $(CC_X86_64) $(QEMU_INCLUDES) $(CFLAGS) $(LDFLAGS) -o $@ $(. - */ -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "qemu/cutils.h" - -#define TESTPATH "/tmp/linux-test.tmp" -#define TESTPORT 7654 -#define STACK_SIZE 16384 - -void error1(const char *filename, int line, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "%s:%d: ", filename, line); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - exit(1); -} - -int __chk_error(const char *filename, int line, int ret) -{ - if (ret < 0) { - error1(filename, line, "%m (ret=%d, errno=%d)", - ret, errno); - } - return ret; -} - -#define error(fmt, ...) error1(__FILE__, __LINE__, fmt, ## __VA_ARGS__) - -#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret)) - -/*******************************************************/ - -#define FILE_BUF_SIZE 300 - -void test_file(void) -{ - int fd, i, len, ret; - uint8_t buf[FILE_BUF_SIZE]; - uint8_t buf2[FILE_BUF_SIZE]; - uint8_t buf3[FILE_BUF_SIZE]; - char cur_dir[1024]; - struct stat st; - struct utimbuf tbuf; - struct iovec vecs[2]; - DIR *dir; - struct dirent *de; - - /* clean up, just in case */ - unlink(TESTPATH "/file1"); - unlink(TESTPATH "/file2"); - unlink(TESTPATH "/file3"); - rmdir(TESTPATH); - - if (getcwd(cur_dir, sizeof(cur_dir)) == NULL) - error("getcwd"); - - chk_error(mkdir(TESTPATH, 0755)); - - chk_error(chdir(TESTPATH)); - - /* open/read/write/close/readv/writev/lseek */ - - fd = chk_error(open("file1", O_WRONLY | O_TRUNC | O_CREAT, 0644)); - for(i=0;i < FILE_BUF_SIZE; i++) - buf[i] = i; - len = chk_error(write(fd, buf, FILE_BUF_SIZE / 2)); - if (len != (FILE_BUF_SIZE / 2)) - error("write"); - vecs[0].iov_base = buf + (FILE_BUF_SIZE / 2); - vecs[0].iov_len = 16; - vecs[1].iov_base = buf + (FILE_BUF_SIZE / 2) + 16; - vecs[1].iov_len = (FILE_BUF_SIZE / 2) - 16; - len = chk_error(writev(fd, vecs, 2)); - if (len != (FILE_BUF_SIZE / 2)) - error("writev"); - chk_error(close(fd)); - - chk_error(rename("file1", "file2")); - - fd = chk_error(open("file2", O_RDONLY)); - - len = chk_error(read(fd, buf2, FILE_BUF_SIZE)); - if (len != FILE_BUF_SIZE) - error("read"); - if (memcmp(buf, buf2, FILE_BUF_SIZE) != 0) - error("memcmp"); - -#define FOFFSET 16 - ret = chk_error(lseek(fd, FOFFSET, SEEK_SET)); - if (ret != 16) - error("lseek"); - vecs[0].iov_base = buf3; - vecs[0].iov_len = 32; - vecs[1].iov_base = buf3 + 32; - vecs[1].iov_len = FILE_BUF_SIZE - FOFFSET - 32; - len = chk_error(readv(fd, vecs, 2)); - if (len != FILE_BUF_SIZE - FOFFSET) - error("readv"); - if (memcmp(buf + FOFFSET, buf3, FILE_BUF_SIZE - FOFFSET) != 0) - error("memcmp"); - - chk_error(close(fd)); - - /* access */ - chk_error(access("file2", R_OK)); - - /* stat/chmod/utime/truncate */ - - chk_error(chmod("file2", 0600)); - tbuf.actime = 1001; - tbuf.modtime = 1000; - chk_error(truncate("file2", 100)); - chk_error(utime("file2", &tbuf)); - chk_error(stat("file2", &st)); - if (st.st_size != 100) - error("stat size"); - if (!S_ISREG(st.st_mode)) - error("stat mode"); - if ((st.st_mode & 0777) != 0600) - error("stat mode2"); - if (st.st_atime != 1001 || - st.st_mtime != 1000) - error("stat time"); - - chk_error(stat(TESTPATH, &st)); - if (!S_ISDIR(st.st_mode)) - error("stat mode"); - - /* fstat */ - fd = chk_error(open("file2", O_RDWR)); - chk_error(ftruncate(fd, 50)); - chk_error(fstat(fd, &st)); - chk_error(close(fd)); - - if (st.st_size != 50) - error("stat size"); - if (!S_ISREG(st.st_mode)) - error("stat mode"); - - /* symlink/lstat */ - chk_error(symlink("file2", "file3")); - chk_error(lstat("file3", &st)); - if (!S_ISLNK(st.st_mode)) - error("stat mode"); - - /* getdents */ - dir = opendir(TESTPATH); - if (!dir) - error("opendir"); - len = 0; - for(;;) { - de = readdir(dir); - if (!de) - break; - if (strcmp(de->d_name, ".") != 0 && - strcmp(de->d_name, "..") != 0 && - strcmp(de->d_name, "file2") != 0 && - strcmp(de->d_name, "file3") != 0) - error("readdir"); - len++; - } - closedir(dir); - if (len != 4) - error("readdir"); - - chk_error(unlink("file3")); - chk_error(unlink("file2")); - chk_error(chdir(cur_dir)); - chk_error(rmdir(TESTPATH)); -} - -void test_fork(void) -{ - int pid, status; - - pid = chk_error(fork()); - if (pid == 0) { - /* child */ - exit(2); - } - chk_error(waitpid(pid, &status, 0)); - if (!WIFEXITED(status) || WEXITSTATUS(status) != 2) - error("waitpid status=0x%x", status); -} - -void test_time(void) -{ - struct timeval tv, tv2; - struct timespec ts, rem; - struct rusage rusg1, rusg2; - int ti, i; - - chk_error(gettimeofday(&tv, NULL)); - rem.tv_sec = 1; - ts.tv_sec = 0; - ts.tv_nsec = 20 * 1000000; - chk_error(nanosleep(&ts, &rem)); - if (rem.tv_sec != 1) - error("nanosleep"); - chk_error(gettimeofday(&tv2, NULL)); - ti = tv2.tv_sec - tv.tv_sec; - if (ti >= 2) - error("gettimeofday"); - - chk_error(getrusage(RUSAGE_SELF, &rusg1)); - for(i = 0;i < 10000; i++); - chk_error(getrusage(RUSAGE_SELF, &rusg2)); - if ((rusg2.ru_utime.tv_sec - rusg1.ru_utime.tv_sec) < 0 || - (rusg2.ru_stime.tv_sec - rusg1.ru_stime.tv_sec) < 0) - error("getrusage"); -} - -void pstrcpy(char *buf, int buf_size, const char *str) -{ - int c; - char *q = buf; - - if (buf_size <= 0) - return; - - for(;;) { - c = *str++; - if (c == 0 || q >= buf + buf_size - 1) - break; - *q++ = c; - } - *q = '\0'; -} - -/* strcat and truncate. */ -char *pstrcat(char *buf, int buf_size, const char *s) -{ - int len; - len = strlen(buf); - if (len < buf_size) - pstrcpy(buf + len, buf_size - len, s); - return buf; -} - -int server_socket(void) -{ - int val, fd; - struct sockaddr_in sockaddr; - - /* server socket */ - fd = chk_error(socket(PF_INET, SOCK_STREAM, 0)); - - val = 1; - chk_error(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))); - - sockaddr.sin_family = AF_INET; - sockaddr.sin_port = htons(TESTPORT); - sockaddr.sin_addr.s_addr = 0; - chk_error(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))); - chk_error(listen(fd, 0)); - return fd; - -} - -int client_socket(void) -{ - int fd; - struct sockaddr_in sockaddr; - - /* server socket */ - fd = chk_error(socket(PF_INET, SOCK_STREAM, 0)); - sockaddr.sin_family = AF_INET; - sockaddr.sin_port = htons(TESTPORT); - inet_aton("127.0.0.1", &sockaddr.sin_addr); - chk_error(connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))); - return fd; -} - -const char socket_msg[] = "hello socket\n"; - -void test_socket(void) -{ - int server_fd, client_fd, fd, pid, ret, val; - struct sockaddr_in sockaddr; - socklen_t len; - char buf[512]; - - server_fd = server_socket(); - - /* test a few socket options */ - len = sizeof(val); - chk_error(getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &val, &len)); - if (val != SOCK_STREAM) - error("getsockopt"); - - pid = chk_error(fork()); - if (pid == 0) { - client_fd = client_socket(); - send(client_fd, socket_msg, sizeof(socket_msg), 0); - close(client_fd); - exit(0); - } - len = sizeof(sockaddr); - fd = chk_error(accept(server_fd, (struct sockaddr *)&sockaddr, &len)); - - ret = chk_error(recv(fd, buf, sizeof(buf), 0)); - if (ret != sizeof(socket_msg)) - error("recv"); - if (memcmp(buf, socket_msg, sizeof(socket_msg)) != 0) - error("socket_msg"); - chk_error(close(fd)); - chk_error(close(server_fd)); -} - -#define WCOUNT_MAX 512 - -void test_pipe(void) -{ - fd_set rfds, wfds; - int fds[2], fd_max, ret; - uint8_t ch; - int wcount, rcount; - - chk_error(pipe(fds)); - chk_error(fcntl(fds[0], F_SETFL, O_NONBLOCK)); - chk_error(fcntl(fds[1], F_SETFL, O_NONBLOCK)); - wcount = 0; - rcount = 0; - for(;;) { - FD_ZERO(&rfds); - fd_max = fds[0]; - FD_SET(fds[0], &rfds); - - FD_ZERO(&wfds); - FD_SET(fds[1], &wfds); - if (fds[1] > fd_max) - fd_max = fds[1]; - - ret = chk_error(select(fd_max + 1, &rfds, &wfds, NULL, NULL)); - if (ret > 0) { - if (FD_ISSET(fds[0], &rfds)) { - chk_error(read(fds[0], &ch, 1)); - rcount++; - if (rcount >= WCOUNT_MAX) - break; - } - if (FD_ISSET(fds[1], &wfds)) { - ch = 'a'; - chk_error(write(fds[0], &ch, 1)); - wcount++; - } - } - } - chk_error(close(fds[0])); - chk_error(close(fds[1])); -} - -int thread1_res; -int thread2_res; - -int thread1_func(void *arg) -{ - int i; - for(i=0;i<5;i++) { - thread1_res++; - usleep(10 * 1000); - } - return 0; -} - -int thread2_func(void *arg) -{ - int i; - for(i=0;i<6;i++) { - thread2_res++; - usleep(10 * 1000); - } - return 0; -} - -void test_clone(void) -{ - uint8_t *stack1, *stack2; - int pid1, pid2, status1, status2; - - stack1 = malloc(STACK_SIZE); - pid1 = chk_error(clone(thread1_func, stack1 + STACK_SIZE, - CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1")); - - stack2 = malloc(STACK_SIZE); - pid2 = chk_error(clone(thread2_func, stack2 + STACK_SIZE, - CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2")); - - while (waitpid(pid1, &status1, 0) != pid1); - free(stack1); - while (waitpid(pid2, &status2, 0) != pid2); - free(stack2); - if (thread1_res != 5 || - thread2_res != 6) - error("clone"); -} - -/***********************************/ - -volatile int alarm_count; -jmp_buf jmp_env; - -void sig_alarm(int sig) -{ - if (sig != SIGALRM) - error("signal"); - alarm_count++; -} - -void sig_segv(int sig, siginfo_t *info, void *puc) -{ - if (sig != SIGSEGV) - error("signal"); - longjmp(jmp_env, 1); -} - -void test_signal(void) -{ - struct sigaction act; - struct itimerval it, oit; - - /* timer test */ - - alarm_count = 0; - - act.sa_handler = sig_alarm; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - chk_error(sigaction(SIGALRM, &act, NULL)); - - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = 10 * 1000; - it.it_value.tv_sec = 0; - it.it_value.tv_usec = 10 * 1000; - chk_error(setitimer(ITIMER_REAL, &it, NULL)); - chk_error(getitimer(ITIMER_REAL, &oit)); - if (oit.it_value.tv_sec != it.it_value.tv_sec || - oit.it_value.tv_usec != it.it_value.tv_usec) - error("itimer"); - - while (alarm_count < 5) { - usleep(10 * 1000); - } - - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = 0; - it.it_value.tv_sec = 0; - it.it_value.tv_usec = 0; - memset(&oit, 0xff, sizeof(oit)); - chk_error(setitimer(ITIMER_REAL, &it, &oit)); - if (oit.it_value.tv_sec != 0 || - oit.it_value.tv_usec != 10 * 1000) - error("setitimer"); - - /* SIGSEGV test */ - act.sa_sigaction = sig_segv; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_SIGINFO; - chk_error(sigaction(SIGSEGV, &act, NULL)); - if (setjmp(jmp_env) == 0) { - *(uint8_t *)0 = 0; - } - - act.sa_handler = SIG_DFL; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - chk_error(sigaction(SIGSEGV, &act, NULL)); -} - -#define SHM_SIZE 32768 - -void test_shm(void) -{ - void *ptr; - int shmid; - - shmid = chk_error(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0777)); - ptr = shmat(shmid, NULL, 0); - if (!ptr) - error("shmat"); - - memset(ptr, 0, SHM_SIZE); - - chk_error(shmctl(shmid, IPC_RMID, 0)); - chk_error(shmdt(ptr)); -} - -int main(int argc, char **argv) -{ - test_file(); - test_fork(); - test_time(); - test_socket(); - // test_clone(); - test_signal(); - test_shm(); - return 0; -} diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target new file mode 100644 index 0000000..90e45a8 --- /dev/null +++ b/tests/tcg/multiarch/Makefile.target @@ -0,0 +1,36 @@ +# -*- Mode: makefile -*- +# +# Multiarch Tests - included from tests/tcg/Makefile.target +# +# These tests are plain C and built without any architecture specific code. +# + +MULTIARCH_SRC=$(SRC_PATH)/tests/tcg/multiarch + +# Set search path for all sources +VPATH += $(MULTIARCH_SRC) +MULTIARCH_SRCS =$(notdir $(wildcard $(MULTIARCH_SRC)/*.c)) +MULTIARCH_TESTS =$(MULTIARCH_SRCS:.c=) + +# Update TESTS +TESTS +=$(MULTIARCH_TESTS) + +# +# The following are any additional rules needed to build things +# + +testthread: LDFLAGS+=-lpthread + +# We define the runner for test-mmap after the individual +# architectures have defined their supported pages sizes. If no +# additional page sizes are defined we only run the default test. + +# default case (host page size) +run-test-mmap: test-mmap + $(call quiet-command, $(QEMU) $< > test-mmap.out, "TEST", \ + "$< (default) on $(TARGET_NAME)") + +# additional page sizes (defined by each architecture adding to EXTRA_RUNS) +run-test-mmap-%: test-mmap + $(call quiet-command, $(QEMU) -p $* $< > test-mmap-$*.out, "TEST", \ + "$< ($* byte pages) on $(TARGET_NAME)") diff --git a/tests/tcg/multiarch/README b/tests/tcg/multiarch/README new file mode 100644 index 0000000..522c9d2 --- /dev/null +++ b/tests/tcg/multiarch/README @@ -0,0 +1 @@ +Multi-architecture linux-user tests diff --git a/tests/tcg/multiarch/linux-test.c b/tests/tcg/multiarch/linux-test.c new file mode 100644 index 0000000..5070d31 --- /dev/null +++ b/tests/tcg/multiarch/linux-test.c @@ -0,0 +1,539 @@ +/* + * linux and CPU test + * + * Copyright (c) 2003 Fabrice Bellard + * + * 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 2 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 . + */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qemu/cutils.h" + +#define TESTPATH "/tmp/linux-test.tmp" +#define TESTPORT 7654 +#define STACK_SIZE 16384 + +void error1(const char *filename, int line, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "%s:%d: ", filename, line); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + exit(1); +} + +int __chk_error(const char *filename, int line, int ret) +{ + if (ret < 0) { + error1(filename, line, "%m (ret=%d, errno=%d)", + ret, errno); + } + return ret; +} + +#define error(fmt, ...) error1(__FILE__, __LINE__, fmt, ## __VA_ARGS__) + +#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret)) + +/*******************************************************/ + +#define FILE_BUF_SIZE 300 + +void test_file(void) +{ + int fd, i, len, ret; + uint8_t buf[FILE_BUF_SIZE]; + uint8_t buf2[FILE_BUF_SIZE]; + uint8_t buf3[FILE_BUF_SIZE]; + char cur_dir[1024]; + struct stat st; + struct utimbuf tbuf; + struct iovec vecs[2]; + DIR *dir; + struct dirent *de; + + /* clean up, just in case */ + unlink(TESTPATH "/file1"); + unlink(TESTPATH "/file2"); + unlink(TESTPATH "/file3"); + rmdir(TESTPATH); + + if (getcwd(cur_dir, sizeof(cur_dir)) == NULL) + error("getcwd"); + + chk_error(mkdir(TESTPATH, 0755)); + + chk_error(chdir(TESTPATH)); + + /* open/read/write/close/readv/writev/lseek */ + + fd = chk_error(open("file1", O_WRONLY | O_TRUNC | O_CREAT, 0644)); + for(i=0;i < FILE_BUF_SIZE; i++) + buf[i] = i; + len = chk_error(write(fd, buf, FILE_BUF_SIZE / 2)); + if (len != (FILE_BUF_SIZE / 2)) + error("write"); + vecs[0].iov_base = buf + (FILE_BUF_SIZE / 2); + vecs[0].iov_len = 16; + vecs[1].iov_base = buf + (FILE_BUF_SIZE / 2) + 16; + vecs[1].iov_len = (FILE_BUF_SIZE / 2) - 16; + len = chk_error(writev(fd, vecs, 2)); + if (len != (FILE_BUF_SIZE / 2)) + error("writev"); + chk_error(close(fd)); + + chk_error(rename("file1", "file2")); + + fd = chk_error(open("file2", O_RDONLY)); + + len = chk_error(read(fd, buf2, FILE_BUF_SIZE)); + if (len != FILE_BUF_SIZE) + error("read"); + if (memcmp(buf, buf2, FILE_BUF_SIZE) != 0) + error("memcmp"); + +#define FOFFSET 16 + ret = chk_error(lseek(fd, FOFFSET, SEEK_SET)); + if (ret != 16) + error("lseek"); + vecs[0].iov_base = buf3; + vecs[0].iov_len = 32; + vecs[1].iov_base = buf3 + 32; + vecs[1].iov_len = FILE_BUF_SIZE - FOFFSET - 32; + len = chk_error(readv(fd, vecs, 2)); + if (len != FILE_BUF_SIZE - FOFFSET) + error("readv"); + if (memcmp(buf + FOFFSET, buf3, FILE_BUF_SIZE - FOFFSET) != 0) + error("memcmp"); + + chk_error(close(fd)); + + /* access */ + chk_error(access("file2", R_OK)); + + /* stat/chmod/utime/truncate */ + + chk_error(chmod("file2", 0600)); + tbuf.actime = 1001; + tbuf.modtime = 1000; + chk_error(truncate("file2", 100)); + chk_error(utime("file2", &tbuf)); + chk_error(stat("file2", &st)); + if (st.st_size != 100) + error("stat size"); + if (!S_ISREG(st.st_mode)) + error("stat mode"); + if ((st.st_mode & 0777) != 0600) + error("stat mode2"); + if (st.st_atime != 1001 || + st.st_mtime != 1000) + error("stat time"); + + chk_error(stat(TESTPATH, &st)); + if (!S_ISDIR(st.st_mode)) + error("stat mode"); + + /* fstat */ + fd = chk_error(open("file2", O_RDWR)); + chk_error(ftruncate(fd, 50)); + chk_error(fstat(fd, &st)); + chk_error(close(fd)); + + if (st.st_size != 50) + error("stat size"); + if (!S_ISREG(st.st_mode)) + error("stat mode"); + + /* symlink/lstat */ + chk_error(symlink("file2", "file3")); + chk_error(lstat("file3", &st)); + if (!S_ISLNK(st.st_mode)) + error("stat mode"); + + /* getdents */ + dir = opendir(TESTPATH); + if (!dir) + error("opendir"); + len = 0; + for(;;) { + de = readdir(dir); + if (!de) + break; + if (strcmp(de->d_name, ".") != 0 && + strcmp(de->d_name, "..") != 0 && + strcmp(de->d_name, "file2") != 0 && + strcmp(de->d_name, "file3") != 0) + error("readdir"); + len++; + } + closedir(dir); + if (len != 4) + error("readdir"); + + chk_error(unlink("file3")); + chk_error(unlink("file2")); + chk_error(chdir(cur_dir)); + chk_error(rmdir(TESTPATH)); +} + +void test_fork(void) +{ + int pid, status; + + pid = chk_error(fork()); + if (pid == 0) { + /* child */ + exit(2); + } + chk_error(waitpid(pid, &status, 0)); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 2) + error("waitpid status=0x%x", status); +} + +void test_time(void) +{ + struct timeval tv, tv2; + struct timespec ts, rem; + struct rusage rusg1, rusg2; + int ti, i; + + chk_error(gettimeofday(&tv, NULL)); + rem.tv_sec = 1; + ts.tv_sec = 0; + ts.tv_nsec = 20 * 1000000; + chk_error(nanosleep(&ts, &rem)); + if (rem.tv_sec != 1) + error("nanosleep"); + chk_error(gettimeofday(&tv2, NULL)); + ti = tv2.tv_sec - tv.tv_sec; + if (ti >= 2) + error("gettimeofday"); + + chk_error(getrusage(RUSAGE_SELF, &rusg1)); + for(i = 0;i < 10000; i++); + chk_error(getrusage(RUSAGE_SELF, &rusg2)); + if ((rusg2.ru_utime.tv_sec - rusg1.ru_utime.tv_sec) < 0 || + (rusg2.ru_stime.tv_sec - rusg1.ru_stime.tv_sec) < 0) + error("getrusage"); +} + +void pstrcpy(char *buf, int buf_size, const char *str) +{ + int c; + char *q = buf; + + if (buf_size <= 0) + return; + + for(;;) { + c = *str++; + if (c == 0 || q >= buf + buf_size - 1) + break; + *q++ = c; + } + *q = '\0'; +} + +/* strcat and truncate. */ +char *pstrcat(char *buf, int buf_size, const char *s) +{ + int len; + len = strlen(buf); + if (len < buf_size) + pstrcpy(buf + len, buf_size - len, s); + return buf; +} + +int server_socket(void) +{ + int val, fd; + struct sockaddr_in sockaddr; + + /* server socket */ + fd = chk_error(socket(PF_INET, SOCK_STREAM, 0)); + + val = 1; + chk_error(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))); + + sockaddr.sin_family = AF_INET; + sockaddr.sin_port = htons(TESTPORT); + sockaddr.sin_addr.s_addr = 0; + chk_error(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))); + chk_error(listen(fd, 0)); + return fd; + +} + +int client_socket(void) +{ + int fd; + struct sockaddr_in sockaddr; + + /* server socket */ + fd = chk_error(socket(PF_INET, SOCK_STREAM, 0)); + sockaddr.sin_family = AF_INET; + sockaddr.sin_port = htons(TESTPORT); + inet_aton("127.0.0.1", &sockaddr.sin_addr); + chk_error(connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))); + return fd; +} + +const char socket_msg[] = "hello socket\n"; + +void test_socket(void) +{ + int server_fd, client_fd, fd, pid, ret, val; + struct sockaddr_in sockaddr; + socklen_t len; + char buf[512]; + + server_fd = server_socket(); + + /* test a few socket options */ + len = sizeof(val); + chk_error(getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &val, &len)); + if (val != SOCK_STREAM) + error("getsockopt"); + + pid = chk_error(fork()); + if (pid == 0) { + client_fd = client_socket(); + send(client_fd, socket_msg, sizeof(socket_msg), 0); + close(client_fd); + exit(0); + } + len = sizeof(sockaddr); + fd = chk_error(accept(server_fd, (struct sockaddr *)&sockaddr, &len)); + + ret = chk_error(recv(fd, buf, sizeof(buf), 0)); + if (ret != sizeof(socket_msg)) + error("recv"); + if (memcmp(buf, socket_msg, sizeof(socket_msg)) != 0) + error("socket_msg"); + chk_error(close(fd)); + chk_error(close(server_fd)); +} + +#define WCOUNT_MAX 512 + +void test_pipe(void) +{ + fd_set rfds, wfds; + int fds[2], fd_max, ret; + uint8_t ch; + int wcount, rcount; + + chk_error(pipe(fds)); + chk_error(fcntl(fds[0], F_SETFL, O_NONBLOCK)); + chk_error(fcntl(fds[1], F_SETFL, O_NONBLOCK)); + wcount = 0; + rcount = 0; + for(;;) { + FD_ZERO(&rfds); + fd_max = fds[0]; + FD_SET(fds[0], &rfds); + + FD_ZERO(&wfds); + FD_SET(fds[1], &wfds); + if (fds[1] > fd_max) + fd_max = fds[1]; + + ret = chk_error(select(fd_max + 1, &rfds, &wfds, NULL, NULL)); + if (ret > 0) { + if (FD_ISSET(fds[0], &rfds)) { + chk_error(read(fds[0], &ch, 1)); + rcount++; + if (rcount >= WCOUNT_MAX) + break; + } + if (FD_ISSET(fds[1], &wfds)) { + ch = 'a'; + chk_error(write(fds[0], &ch, 1)); + wcount++; + } + } + } + chk_error(close(fds[0])); + chk_error(close(fds[1])); +} + +int thread1_res; +int thread2_res; + +int thread1_func(void *arg) +{ + int i; + for(i=0;i<5;i++) { + thread1_res++; + usleep(10 * 1000); + } + return 0; +} + +int thread2_func(void *arg) +{ + int i; + for(i=0;i<6;i++) { + thread2_res++; + usleep(10 * 1000); + } + return 0; +} + +void test_clone(void) +{ + uint8_t *stack1, *stack2; + int pid1, pid2, status1, status2; + + stack1 = malloc(STACK_SIZE); + pid1 = chk_error(clone(thread1_func, stack1 + STACK_SIZE, + CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1")); + + stack2 = malloc(STACK_SIZE); + pid2 = chk_error(clone(thread2_func, stack2 + STACK_SIZE, + CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2")); + + while (waitpid(pid1, &status1, 0) != pid1); + free(stack1); + while (waitpid(pid2, &status2, 0) != pid2); + free(stack2); + if (thread1_res != 5 || + thread2_res != 6) + error("clone"); +} + +/***********************************/ + +volatile int alarm_count; +jmp_buf jmp_env; + +void sig_alarm(int sig) +{ + if (sig != SIGALRM) + error("signal"); + alarm_count++; +} + +void sig_segv(int sig, siginfo_t *info, void *puc) +{ + if (sig != SIGSEGV) + error("signal"); + longjmp(jmp_env, 1); +} + +void test_signal(void) +{ + struct sigaction act; + struct itimerval it, oit; + + /* timer test */ + + alarm_count = 0; + + act.sa_handler = sig_alarm; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + chk_error(sigaction(SIGALRM, &act, NULL)); + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 10 * 1000; + it.it_value.tv_sec = 0; + it.it_value.tv_usec = 10 * 1000; + chk_error(setitimer(ITIMER_REAL, &it, NULL)); + chk_error(getitimer(ITIMER_REAL, &oit)); + if (oit.it_value.tv_sec != it.it_value.tv_sec || + oit.it_value.tv_usec != it.it_value.tv_usec) + error("itimer"); + + while (alarm_count < 5) { + usleep(10 * 1000); + } + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + it.it_value.tv_sec = 0; + it.it_value.tv_usec = 0; + memset(&oit, 0xff, sizeof(oit)); + chk_error(setitimer(ITIMER_REAL, &it, &oit)); + if (oit.it_value.tv_sec != 0 || + oit.it_value.tv_usec != 10 * 1000) + error("setitimer"); + + /* SIGSEGV test */ + act.sa_sigaction = sig_segv; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + chk_error(sigaction(SIGSEGV, &act, NULL)); + if (setjmp(jmp_env) == 0) { + *(uint8_t *)0 = 0; + } + + act.sa_handler = SIG_DFL; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + chk_error(sigaction(SIGSEGV, &act, NULL)); +} + +#define SHM_SIZE 32768 + +void test_shm(void) +{ + void *ptr; + int shmid; + + shmid = chk_error(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0777)); + ptr = shmat(shmid, NULL, 0); + if (!ptr) + error("shmat"); + + memset(ptr, 0, SHM_SIZE); + + chk_error(shmctl(shmid, IPC_RMID, 0)); + chk_error(shmdt(ptr)); +} + +int main(int argc, char **argv) +{ + test_file(); + test_fork(); + test_time(); + test_socket(); + // test_clone(); + test_signal(); + test_shm(); + return 0; +} diff --git a/tests/tcg/multiarch/sha1.c b/tests/tcg/multiarch/sha1.c new file mode 100644 index 0000000..93b7c8e --- /dev/null +++ b/tests/tcg/multiarch/sha1.c @@ -0,0 +1,240 @@ + +/* from valgrind tests */ + +/* ================ sha1.c ================ */ +/* +SHA-1 in C +By Steve Reid +100% Public Domain + +Test Vectors (from FIPS PUB 180-1) +"abc" + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ +/* #define SHA1HANDSOFF * Copies data before messing with it. */ + +#define SHA1HANDSOFF + +#include +#include +#include + +/* ================ sha1.h ================ */ +/* +SHA-1 in C +By Steve Reid +100% Public Domain +*/ + +typedef struct { + uint32_t state[5]; + uint32_t count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); +void SHA1Init(SHA1_CTX* context); +void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); +void SHA1Final(unsigned char digest[20], SHA1_CTX* context); +/* ================ end of sha1.h ================ */ +#include + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#if BYTE_ORDER == LITTLE_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#elif BYTE_ORDER == BIG_ENDIAN +#define blk0(i) block->l[i] +#else +#error "Endianness not defined!" +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) +{ +uint32_t a, b, c, d, e; +typedef union { + unsigned char c[64]; + uint32_t l[16]; +} CHAR64LONG16; +#ifdef SHA1HANDSOFF +CHAR64LONG16 block[1]; /* use array to appear as a pointer */ + memcpy(block, buffer, 64); +#else + /* The following had better never be used because it causes the + * pointer-to-const buffer to be cast into a pointer to non-const. + * And the result is written through. I threw a "const" in, hoping + * this will cause a diagnostic. + */ +CHAR64LONG16* block = (const CHAR64LONG16*)buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +#ifdef SHA1HANDSOFF + memset(block, '\0', sizeof(block)); +#endif +} + + +/* SHA1Init - Initialize new context */ + +void SHA1Init(SHA1_CTX* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len) +{ +uint32_t i; +uint32_t j; + + j = context->count[0]; + if ((context->count[0] += len << 3) < j) + context->count[1]++; + context->count[1] += (len>>29); + j = (j >> 3) & 63; + if ((j + len) > 63) { + memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else i = 0; + memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ + +void SHA1Final(unsigned char digest[20], SHA1_CTX* context) +{ +unsigned i; +unsigned char finalcount[8]; +unsigned char c; + +#if 0 /* untested "improvement" by DHR */ + /* Convert context->count to a sequence of bytes + * in finalcount. Second element first, but + * big-endian order within element. + * But we do it all backwards. + */ + unsigned char *fcp = &finalcount[8]; + + for (i = 0; i < 2; i++) + { + uint32_t t = context->count[i]; + int j; + + for (j = 0; j < 4; t >>= 8, j++) + *--fcp = (unsigned char) t; + } +#else + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } +#endif + c = 0200; + SHA1Update(context, &c, 1); + while ((context->count[0] & 504) != 448) { + c = 0000; + SHA1Update(context, &c, 1); + } + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + memset(context, '\0', sizeof(*context)); + memset(&finalcount, '\0', sizeof(finalcount)); +} +/* ================ end of sha1.c ================ */ + +#define BUFSIZE 4096 + +int +main(int argc, char **argv) +{ + SHA1_CTX ctx; + unsigned char hash[20], buf[BUFSIZE]; + int i; + + for(i=0;i. + */ + +#include +#include +#include +#include +#include + +#include + +#define D(x) + +#define fail_unless(x) \ +do \ +{ \ + if (!(x)) { \ + fprintf (stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \ + exit (EXIT_FAILURE); \ + } \ +} while (0) + +unsigned char *dummybuf; +static unsigned int pagesize; +static unsigned int pagemask; +int test_fd; +size_t test_fsize; + +void check_aligned_anonymous_unfixed_mmaps(void) +{ + void *p1; + void *p2; + void *p3; + void *p4; + void *p5; + uintptr_t p; + int i; + + fprintf (stderr, "%s", __func__); + for (i = 0; i < 0x1fff; i++) + { + size_t len; + + len = pagesize + (pagesize * i & 7); + p1 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + p2 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + p3 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + p4 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + p5 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + fail_unless (p1 != MAP_FAILED); + fail_unless (p2 != MAP_FAILED); + fail_unless (p3 != MAP_FAILED); + fail_unless (p4 != MAP_FAILED); + fail_unless (p5 != MAP_FAILED); + p = (uintptr_t) p1; + D(printf ("p=%x\n", p)); + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p2; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p3; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p4; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p5; + fail_unless ((p & pagemask) == 0); + + /* Make sure we can read from the entire area. */ + memcpy (dummybuf, p1, pagesize); + memcpy (dummybuf, p2, pagesize); + memcpy (dummybuf, p3, pagesize); + memcpy (dummybuf, p4, pagesize); + memcpy (dummybuf, p5, pagesize); + + munmap (p1, len); + munmap (p2, len); + munmap (p3, len); + munmap (p4, len); + munmap (p5, len); + } + fprintf (stderr, " passed\n"); +} + +void check_large_anonymous_unfixed_mmap(void) +{ + void *p1; + uintptr_t p; + size_t len; + + fprintf (stderr, "%s", __func__); + + len = 0x02000000; + p1 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + fail_unless (p1 != MAP_FAILED); + p = (uintptr_t) p1; + fail_unless ((p & pagemask) == 0); + + /* Make sure we can read from the entire area. */ + memcpy (dummybuf, p1, pagesize); + munmap (p1, len); + fprintf (stderr, " passed\n"); +} + +void check_aligned_anonymous_unfixed_colliding_mmaps(void) +{ + char *p1; + char *p2; + char *p3; + uintptr_t p; + int i; + + fprintf (stderr, "%s", __func__); + for (i = 0; i < 0x2fff; i++) + { + int nlen; + p1 = mmap(NULL, pagesize, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + fail_unless (p1 != MAP_FAILED); + p = (uintptr_t) p1; + fail_unless ((p & pagemask) == 0); + memcpy (dummybuf, p1, pagesize); + + p2 = mmap(NULL, pagesize, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + fail_unless (p2 != MAP_FAILED); + p = (uintptr_t) p2; + fail_unless ((p & pagemask) == 0); + memcpy (dummybuf, p2, pagesize); + + + munmap (p1, pagesize); + nlen = pagesize * 8; + p3 = mmap(NULL, nlen, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + fail_unless (p3 != MAP_FAILED); + + /* Check if the mmaped areas collide. */ + if (p3 < p2 + && (p3 + nlen) > p2) + fail_unless (0); + + memcpy (dummybuf, p3, pagesize); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + p = (uintptr_t) p3; + fail_unless ((p & pagemask) == 0); + munmap (p2, pagesize); + munmap (p3, nlen); + } + fprintf (stderr, " passed\n"); +} + +void check_aligned_anonymous_fixed_mmaps(void) +{ + char *addr; + void *p1; + uintptr_t p; + int i; + + /* Find a suitable address to start with. */ + addr = mmap(NULL, pagesize * 40, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + fprintf (stderr, "%s addr=%p", __func__, addr); + fail_unless (addr != MAP_FAILED); + + for (i = 0; i < 40; i++) + { + /* Create submaps within our unfixed map. */ + p1 = mmap(addr, pagesize, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, 0); + /* Make sure we get pages aligned with the pagesize. + The target expects this. */ + p = (uintptr_t) p1; + fail_unless (p1 == addr); + fail_unless ((p & pagemask) == 0); + memcpy (dummybuf, p1, pagesize); + munmap (p1, pagesize); + addr += pagesize; + } + fprintf (stderr, " passed\n"); +} + +void check_aligned_anonymous_fixed_mmaps_collide_with_host(void) +{ + char *addr; + void *p1; + uintptr_t p; + int i; + + /* Find a suitable address to start with. Right were the x86 hosts + stack is. */ + addr = ((void *)0x80000000); + fprintf (stderr, "%s addr=%p", __func__, addr); + fprintf (stderr, "FIXME: QEMU fails to track pages used by the host."); + + for (i = 0; i < 20; i++) + { + /* Create submaps within our unfixed map. */ + p1 = mmap(addr, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, 0); + /* Make sure we get pages aligned with the pagesize. + The target expects this. */ + p = (uintptr_t) p1; + fail_unless (p1 == addr); + fail_unless ((p & pagemask) == 0); + memcpy (p1, dummybuf, pagesize); + munmap (p1, pagesize); + addr += pagesize; + } + fprintf (stderr, " passed\n"); +} + +void check_file_unfixed_mmaps(void) +{ + unsigned int *p1, *p2, *p3; + uintptr_t p; + int i; + + fprintf (stderr, "%s", __func__); + for (i = 0; i < 0x10; i++) + { + size_t len; + + len = pagesize; + p1 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE, + test_fd, 0); + p2 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE, + test_fd, pagesize); + p3 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE, + test_fd, pagesize * 2); + + fail_unless (p1 != MAP_FAILED); + fail_unless (p2 != MAP_FAILED); + fail_unless (p3 != MAP_FAILED); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + p = (uintptr_t) p1; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p2; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p3; + fail_unless ((p & pagemask) == 0); + + /* Verify that the file maps was made correctly. */ + D(printf ("p1=%d p2=%d p3=%d\n", *p1, *p2, *p3)); + fail_unless (*p1 == 0); + fail_unless (*p2 == (pagesize / sizeof *p2)); + fail_unless (*p3 == ((pagesize * 2) / sizeof *p3)); + + memcpy (dummybuf, p1, pagesize); + memcpy (dummybuf, p2, pagesize); + memcpy (dummybuf, p3, pagesize); + munmap (p1, len); + munmap (p2, len); + munmap (p3, len); + } + fprintf (stderr, " passed\n"); +} + +void check_file_unfixed_eof_mmaps(void) +{ + char *cp; + unsigned int *p1; + uintptr_t p; + int i; + + fprintf (stderr, "%s", __func__); + for (i = 0; i < 0x10; i++) + { + p1 = mmap(NULL, pagesize, PROT_READ, + MAP_PRIVATE, + test_fd, + (test_fsize - sizeof *p1) & ~pagemask); + + fail_unless (p1 != MAP_FAILED); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + p = (uintptr_t) p1; + fail_unless ((p & pagemask) == 0); + /* Verify that the file maps was made correctly. */ + fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1] + == ((test_fsize - sizeof *p1) / sizeof *p1)); + + /* Verify that the end of page is accessible and zeroed. */ + cp = (void *) p1; + fail_unless (cp[pagesize - 4] == 0); + munmap (p1, pagesize); + } + fprintf (stderr, " passed\n"); +} + +void check_file_fixed_eof_mmaps(void) +{ + char *addr; + char *cp; + unsigned int *p1; + uintptr_t p; + int i; + + /* Find a suitable address to start with. */ + addr = mmap(NULL, pagesize * 44, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + + fprintf (stderr, "%s addr=%p", __func__, (void *)addr); + fail_unless (addr != MAP_FAILED); + + for (i = 0; i < 0x10; i++) + { + /* Create submaps within our unfixed map. */ + p1 = mmap(addr, pagesize, PROT_READ, + MAP_PRIVATE | MAP_FIXED, + test_fd, + (test_fsize - sizeof *p1) & ~pagemask); + + fail_unless (p1 != MAP_FAILED); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + p = (uintptr_t) p1; + fail_unless ((p & pagemask) == 0); + + /* Verify that the file maps was made correctly. */ + fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1] + == ((test_fsize - sizeof *p1) / sizeof *p1)); + + /* Verify that the end of page is accessible and zeroed. */ + cp = (void *)p1; + fail_unless (cp[pagesize - 4] == 0); + munmap (p1, pagesize); + addr += pagesize; + } + fprintf (stderr, " passed\n"); +} + +void check_file_fixed_mmaps(void) +{ + unsigned char *addr; + unsigned int *p1, *p2, *p3, *p4; + int i; + + /* Find a suitable address to start with. */ + addr = mmap(NULL, pagesize * 40 * 4, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + fprintf (stderr, "%s addr=%p", __func__, (void *)addr); + fail_unless (addr != MAP_FAILED); + + for (i = 0; i < 40; i++) + { + p1 = mmap(addr, pagesize, PROT_READ, + MAP_PRIVATE | MAP_FIXED, + test_fd, 0); + p2 = mmap(addr + pagesize, pagesize, PROT_READ, + MAP_PRIVATE | MAP_FIXED, + test_fd, pagesize); + p3 = mmap(addr + pagesize * 2, pagesize, PROT_READ, + MAP_PRIVATE | MAP_FIXED, + test_fd, pagesize * 2); + p4 = mmap(addr + pagesize * 3, pagesize, PROT_READ, + MAP_PRIVATE | MAP_FIXED, + test_fd, pagesize * 3); + + /* Make sure we get pages aligned with the pagesize. + The target expects this. */ + fail_unless (p1 == (void *)addr); + fail_unless (p2 == (void *)addr + pagesize); + fail_unless (p3 == (void *)addr + pagesize * 2); + fail_unless (p4 == (void *)addr + pagesize * 3); + + /* Verify that the file maps was made correctly. */ + fail_unless (*p1 == 0); + fail_unless (*p2 == (pagesize / sizeof *p2)); + fail_unless (*p3 == ((pagesize * 2) / sizeof *p3)); + fail_unless (*p4 == ((pagesize * 3) / sizeof *p4)); + + memcpy (dummybuf, p1, pagesize); + memcpy (dummybuf, p2, pagesize); + memcpy (dummybuf, p3, pagesize); + memcpy (dummybuf, p4, pagesize); + + munmap (p1, pagesize); + munmap (p2, pagesize); + munmap (p3, pagesize); + munmap (p4, pagesize); + addr += pagesize * 4; + } + fprintf (stderr, " passed\n"); +} + +void checked_write(int fd, const void *buf, size_t count) +{ + ssize_t rc = write(fd, buf, count); + fail_unless(rc == count); +} + +int main(int argc, char **argv) +{ + char tempname[] = "/tmp/.cmmapXXXXXX"; + unsigned int i; + + /* Trust the first argument, otherwise probe the system for our + pagesize. */ + if (argc > 1) + pagesize = strtoul(argv[1], NULL, 0); + else + pagesize = sysconf(_SC_PAGESIZE); + + /* Assume pagesize is a power of two. */ + pagemask = pagesize - 1; + dummybuf = malloc (pagesize); + printf ("pagesize=%u pagemask=%x\n", pagesize, pagemask); + + test_fd = mkstemp(tempname); + unlink(tempname); + + /* Fill the file with int's counting from zero and up. */ + for (i = 0; i < (pagesize * 4) / sizeof i; i++) { + checked_write(test_fd, &i, sizeof i); + } + + /* Append a few extra writes to make the file end at non + page boundary. */ + checked_write(test_fd, &i, sizeof i); i++; + checked_write(test_fd, &i, sizeof i); i++; + checked_write(test_fd, &i, sizeof i); i++; + + test_fsize = lseek(test_fd, 0, SEEK_CUR); + + /* Run the tests. */ + check_aligned_anonymous_unfixed_mmaps(); + check_aligned_anonymous_unfixed_colliding_mmaps(); + check_aligned_anonymous_fixed_mmaps(); + check_file_unfixed_mmaps(); + check_file_fixed_mmaps(); + check_file_fixed_eof_mmaps(); + check_file_unfixed_eof_mmaps(); + + /* Fails at the moment. */ + /* check_aligned_anonymous_fixed_mmaps_collide_with_host(); */ + + return EXIT_SUCCESS; +} diff --git a/tests/tcg/multiarch/testthread.c b/tests/tcg/multiarch/testthread.c new file mode 100644 index 0000000..810ba5d --- /dev/null +++ b/tests/tcg/multiarch/testthread.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void checked_write(int fd, const void *buf, size_t count) +{ + ssize_t rc = write(fd, buf, count); + assert(rc == count); +} + +void *thread1_func(void *arg) +{ + int i; + char buf[512]; + + for(i=0;i<10;i++) { + snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg); + checked_write(1, buf, strlen(buf)); + usleep(100 * 1000); + } + return NULL; +} + +void *thread2_func(void *arg) +{ + int i; + char buf[512]; + for(i=0;i<20;i++) { + snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg); + checked_write(1, buf, strlen(buf)); + usleep(150 * 1000); + } + return NULL; +} + +void test_pthread(void) +{ + pthread_t tid1, tid2; + + pthread_create(&tid1, NULL, thread1_func, "hello1"); + pthread_create(&tid2, NULL, thread2_func, "hello2"); + pthread_join(tid1, NULL); + pthread_join(tid2, NULL); + printf("End of pthread test.\n"); +} + +int main(int argc, char **argv) +{ + test_pthread(); + return 0; +} diff --git a/tests/tcg/sha1.c b/tests/tcg/sha1.c deleted file mode 100644 index 93b7c8e..0000000 --- a/tests/tcg/sha1.c +++ /dev/null @@ -1,240 +0,0 @@ - -/* from valgrind tests */ - -/* ================ sha1.c ================ */ -/* -SHA-1 in C -By Steve Reid -100% Public Domain - -Test Vectors (from FIPS PUB 180-1) -"abc" - A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D -"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" - 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 -A million repetitions of "a" - 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F -*/ - -/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ -/* #define SHA1HANDSOFF * Copies data before messing with it. */ - -#define SHA1HANDSOFF - -#include -#include -#include - -/* ================ sha1.h ================ */ -/* -SHA-1 in C -By Steve Reid -100% Public Domain -*/ - -typedef struct { - uint32_t state[5]; - uint32_t count[2]; - unsigned char buffer[64]; -} SHA1_CTX; - -void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); -void SHA1Init(SHA1_CTX* context); -void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); -void SHA1Final(unsigned char digest[20], SHA1_CTX* context); -/* ================ end of sha1.h ================ */ -#include - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -/* blk0() and blk() perform the initial expand. */ -/* I got the idea of expanding during the round function from SSLeay */ -#if BYTE_ORDER == LITTLE_ENDIAN -#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ - |(rol(block->l[i],8)&0x00FF00FF)) -#elif BYTE_ORDER == BIG_ENDIAN -#define blk0(i) block->l[i] -#else -#error "Endianness not defined!" -#endif -#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ - ^block->l[(i+2)&15]^block->l[i&15],1)) - -/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); -#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); -#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); - - -/* Hash a single 512-bit block. This is the core of the algorithm. */ - -void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) -{ -uint32_t a, b, c, d, e; -typedef union { - unsigned char c[64]; - uint32_t l[16]; -} CHAR64LONG16; -#ifdef SHA1HANDSOFF -CHAR64LONG16 block[1]; /* use array to appear as a pointer */ - memcpy(block, buffer, 64); -#else - /* The following had better never be used because it causes the - * pointer-to-const buffer to be cast into a pointer to non-const. - * And the result is written through. I threw a "const" in, hoping - * this will cause a diagnostic. - */ -CHAR64LONG16* block = (const CHAR64LONG16*)buffer; -#endif - /* Copy context->state[] to working vars */ - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - /* 4 rounds of 20 operations each. Loop unrolled. */ - R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); - R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); - R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); - R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); - R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); - R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); - R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); - R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); - R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); - R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); - R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); - R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); - R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); - R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); - R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); - R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); - R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); - R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); - R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); - R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); - /* Add the working vars back into context.state[] */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - /* Wipe variables */ - a = b = c = d = e = 0; -#ifdef SHA1HANDSOFF - memset(block, '\0', sizeof(block)); -#endif -} - - -/* SHA1Init - Initialize new context */ - -void SHA1Init(SHA1_CTX* context) -{ - /* SHA1 initialization constants */ - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; - context->count[0] = context->count[1] = 0; -} - - -/* Run your data through this. */ - -void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len) -{ -uint32_t i; -uint32_t j; - - j = context->count[0]; - if ((context->count[0] += len << 3) < j) - context->count[1]++; - context->count[1] += (len>>29); - j = (j >> 3) & 63; - if ((j + len) > 63) { - memcpy(&context->buffer[j], data, (i = 64-j)); - SHA1Transform(context->state, context->buffer); - for ( ; i + 63 < len; i += 64) { - SHA1Transform(context->state, &data[i]); - } - j = 0; - } - else i = 0; - memcpy(&context->buffer[j], &data[i], len - i); -} - - -/* Add padding and return the message digest. */ - -void SHA1Final(unsigned char digest[20], SHA1_CTX* context) -{ -unsigned i; -unsigned char finalcount[8]; -unsigned char c; - -#if 0 /* untested "improvement" by DHR */ - /* Convert context->count to a sequence of bytes - * in finalcount. Second element first, but - * big-endian order within element. - * But we do it all backwards. - */ - unsigned char *fcp = &finalcount[8]; - - for (i = 0; i < 2; i++) - { - uint32_t t = context->count[i]; - int j; - - for (j = 0; j < 4; t >>= 8, j++) - *--fcp = (unsigned char) t; - } -#else - for (i = 0; i < 8; i++) { - finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ - } -#endif - c = 0200; - SHA1Update(context, &c, 1); - while ((context->count[0] & 504) != 448) { - c = 0000; - SHA1Update(context, &c, 1); - } - SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ - for (i = 0; i < 20; i++) { - digest[i] = (unsigned char) - ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); - } - /* Wipe variables */ - memset(context, '\0', sizeof(*context)); - memset(&finalcount, '\0', sizeof(finalcount)); -} -/* ================ end of sha1.c ================ */ - -#define BUFSIZE 4096 - -int -main(int argc, char **argv) -{ - SHA1_CTX ctx; - unsigned char hash[20], buf[BUFSIZE]; - int i; - - for(i=0;i. - */ - -#include -#include -#include -#include -#include - -#include - -#define D(x) - -#define fail_unless(x) \ -do \ -{ \ - if (!(x)) { \ - fprintf (stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \ - exit (EXIT_FAILURE); \ - } \ -} while (0) - -unsigned char *dummybuf; -static unsigned int pagesize; -static unsigned int pagemask; -int test_fd; -size_t test_fsize; - -void check_aligned_anonymous_unfixed_mmaps(void) -{ - void *p1; - void *p2; - void *p3; - void *p4; - void *p5; - uintptr_t p; - int i; - - fprintf (stderr, "%s", __func__); - for (i = 0; i < 0x1fff; i++) - { - size_t len; - - len = pagesize + (pagesize * i & 7); - p1 = mmap(NULL, len, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - p2 = mmap(NULL, len, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - p3 = mmap(NULL, len, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - p4 = mmap(NULL, len, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - p5 = mmap(NULL, len, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - - /* Make sure we get pages aligned with the pagesize. The - target expects this. */ - fail_unless (p1 != MAP_FAILED); - fail_unless (p2 != MAP_FAILED); - fail_unless (p3 != MAP_FAILED); - fail_unless (p4 != MAP_FAILED); - fail_unless (p5 != MAP_FAILED); - p = (uintptr_t) p1; - D(printf ("p=%x\n", p)); - fail_unless ((p & pagemask) == 0); - p = (uintptr_t) p2; - fail_unless ((p & pagemask) == 0); - p = (uintptr_t) p3; - fail_unless ((p & pagemask) == 0); - p = (uintptr_t) p4; - fail_unless ((p & pagemask) == 0); - p = (uintptr_t) p5; - fail_unless ((p & pagemask) == 0); - - /* Make sure we can read from the entire area. */ - memcpy (dummybuf, p1, pagesize); - memcpy (dummybuf, p2, pagesize); - memcpy (dummybuf, p3, pagesize); - memcpy (dummybuf, p4, pagesize); - memcpy (dummybuf, p5, pagesize); - - munmap (p1, len); - munmap (p2, len); - munmap (p3, len); - munmap (p4, len); - munmap (p5, len); - } - fprintf (stderr, " passed\n"); -} - -void check_large_anonymous_unfixed_mmap(void) -{ - void *p1; - uintptr_t p; - size_t len; - - fprintf (stderr, "%s", __func__); - - len = 0x02000000; - p1 = mmap(NULL, len, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - - /* Make sure we get pages aligned with the pagesize. The - target expects this. */ - fail_unless (p1 != MAP_FAILED); - p = (uintptr_t) p1; - fail_unless ((p & pagemask) == 0); - - /* Make sure we can read from the entire area. */ - memcpy (dummybuf, p1, pagesize); - munmap (p1, len); - fprintf (stderr, " passed\n"); -} - -void check_aligned_anonymous_unfixed_colliding_mmaps(void) -{ - char *p1; - char *p2; - char *p3; - uintptr_t p; - int i; - - fprintf (stderr, "%s", __func__); - for (i = 0; i < 0x2fff; i++) - { - int nlen; - p1 = mmap(NULL, pagesize, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - fail_unless (p1 != MAP_FAILED); - p = (uintptr_t) p1; - fail_unless ((p & pagemask) == 0); - memcpy (dummybuf, p1, pagesize); - - p2 = mmap(NULL, pagesize, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - fail_unless (p2 != MAP_FAILED); - p = (uintptr_t) p2; - fail_unless ((p & pagemask) == 0); - memcpy (dummybuf, p2, pagesize); - - - munmap (p1, pagesize); - nlen = pagesize * 8; - p3 = mmap(NULL, nlen, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - fail_unless (p3 != MAP_FAILED); - - /* Check if the mmaped areas collide. */ - if (p3 < p2 - && (p3 + nlen) > p2) - fail_unless (0); - - memcpy (dummybuf, p3, pagesize); - - /* Make sure we get pages aligned with the pagesize. The - target expects this. */ - p = (uintptr_t) p3; - fail_unless ((p & pagemask) == 0); - munmap (p2, pagesize); - munmap (p3, nlen); - } - fprintf (stderr, " passed\n"); -} - -void check_aligned_anonymous_fixed_mmaps(void) -{ - char *addr; - void *p1; - uintptr_t p; - int i; - - /* Find a suitable address to start with. */ - addr = mmap(NULL, pagesize * 40, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, - -1, 0); - fprintf (stderr, "%s addr=%p", __func__, addr); - fail_unless (addr != MAP_FAILED); - - for (i = 0; i < 40; i++) - { - /* Create submaps within our unfixed map. */ - p1 = mmap(addr, pagesize, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, - -1, 0); - /* Make sure we get pages aligned with the pagesize. - The target expects this. */ - p = (uintptr_t) p1; - fail_unless (p1 == addr); - fail_unless ((p & pagemask) == 0); - memcpy (dummybuf, p1, pagesize); - munmap (p1, pagesize); - addr += pagesize; - } - fprintf (stderr, " passed\n"); -} - -void check_aligned_anonymous_fixed_mmaps_collide_with_host(void) -{ - char *addr; - void *p1; - uintptr_t p; - int i; - - /* Find a suitable address to start with. Right were the x86 hosts - stack is. */ - addr = ((void *)0x80000000); - fprintf (stderr, "%s addr=%p", __func__, addr); - fprintf (stderr, "FIXME: QEMU fails to track pages used by the host."); - - for (i = 0; i < 20; i++) - { - /* Create submaps within our unfixed map. */ - p1 = mmap(addr, pagesize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, - -1, 0); - /* Make sure we get pages aligned with the pagesize. - The target expects this. */ - p = (uintptr_t) p1; - fail_unless (p1 == addr); - fail_unless ((p & pagemask) == 0); - memcpy (p1, dummybuf, pagesize); - munmap (p1, pagesize); - addr += pagesize; - } - fprintf (stderr, " passed\n"); -} - -void check_file_unfixed_mmaps(void) -{ - unsigned int *p1, *p2, *p3; - uintptr_t p; - int i; - - fprintf (stderr, "%s", __func__); - for (i = 0; i < 0x10; i++) - { - size_t len; - - len = pagesize; - p1 = mmap(NULL, len, PROT_READ, - MAP_PRIVATE, - test_fd, 0); - p2 = mmap(NULL, len, PROT_READ, - MAP_PRIVATE, - test_fd, pagesize); - p3 = mmap(NULL, len, PROT_READ, - MAP_PRIVATE, - test_fd, pagesize * 2); - - fail_unless (p1 != MAP_FAILED); - fail_unless (p2 != MAP_FAILED); - fail_unless (p3 != MAP_FAILED); - - /* Make sure we get pages aligned with the pagesize. The - target expects this. */ - p = (uintptr_t) p1; - fail_unless ((p & pagemask) == 0); - p = (uintptr_t) p2; - fail_unless ((p & pagemask) == 0); - p = (uintptr_t) p3; - fail_unless ((p & pagemask) == 0); - - /* Verify that the file maps was made correctly. */ - D(printf ("p1=%d p2=%d p3=%d\n", *p1, *p2, *p3)); - fail_unless (*p1 == 0); - fail_unless (*p2 == (pagesize / sizeof *p2)); - fail_unless (*p3 == ((pagesize * 2) / sizeof *p3)); - - memcpy (dummybuf, p1, pagesize); - memcpy (dummybuf, p2, pagesize); - memcpy (dummybuf, p3, pagesize); - munmap (p1, len); - munmap (p2, len); - munmap (p3, len); - } - fprintf (stderr, " passed\n"); -} - -void check_file_unfixed_eof_mmaps(void) -{ - char *cp; - unsigned int *p1; - uintptr_t p; - int i; - - fprintf (stderr, "%s", __func__); - for (i = 0; i < 0x10; i++) - { - p1 = mmap(NULL, pagesize, PROT_READ, - MAP_PRIVATE, - test_fd, - (test_fsize - sizeof *p1) & ~pagemask); - - fail_unless (p1 != MAP_FAILED); - - /* Make sure we get pages aligned with the pagesize. The - target expects this. */ - p = (uintptr_t) p1; - fail_unless ((p & pagemask) == 0); - /* Verify that the file maps was made correctly. */ - fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1] - == ((test_fsize - sizeof *p1) / sizeof *p1)); - - /* Verify that the end of page is accessible and zeroed. */ - cp = (void *) p1; - fail_unless (cp[pagesize - 4] == 0); - munmap (p1, pagesize); - } - fprintf (stderr, " passed\n"); -} - -void check_file_fixed_eof_mmaps(void) -{ - char *addr; - char *cp; - unsigned int *p1; - uintptr_t p; - int i; - - /* Find a suitable address to start with. */ - addr = mmap(NULL, pagesize * 44, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, - -1, 0); - - fprintf (stderr, "%s addr=%p", __func__, (void *)addr); - fail_unless (addr != MAP_FAILED); - - for (i = 0; i < 0x10; i++) - { - /* Create submaps within our unfixed map. */ - p1 = mmap(addr, pagesize, PROT_READ, - MAP_PRIVATE | MAP_FIXED, - test_fd, - (test_fsize - sizeof *p1) & ~pagemask); - - fail_unless (p1 != MAP_FAILED); - - /* Make sure we get pages aligned with the pagesize. The - target expects this. */ - p = (uintptr_t) p1; - fail_unless ((p & pagemask) == 0); - - /* Verify that the file maps was made correctly. */ - fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1] - == ((test_fsize - sizeof *p1) / sizeof *p1)); - - /* Verify that the end of page is accessible and zeroed. */ - cp = (void *)p1; - fail_unless (cp[pagesize - 4] == 0); - munmap (p1, pagesize); - addr += pagesize; - } - fprintf (stderr, " passed\n"); -} - -void check_file_fixed_mmaps(void) -{ - unsigned char *addr; - unsigned int *p1, *p2, *p3, *p4; - int i; - - /* Find a suitable address to start with. */ - addr = mmap(NULL, pagesize * 40 * 4, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, - -1, 0); - fprintf (stderr, "%s addr=%p", __func__, (void *)addr); - fail_unless (addr != MAP_FAILED); - - for (i = 0; i < 40; i++) - { - p1 = mmap(addr, pagesize, PROT_READ, - MAP_PRIVATE | MAP_FIXED, - test_fd, 0); - p2 = mmap(addr + pagesize, pagesize, PROT_READ, - MAP_PRIVATE | MAP_FIXED, - test_fd, pagesize); - p3 = mmap(addr + pagesize * 2, pagesize, PROT_READ, - MAP_PRIVATE | MAP_FIXED, - test_fd, pagesize * 2); - p4 = mmap(addr + pagesize * 3, pagesize, PROT_READ, - MAP_PRIVATE | MAP_FIXED, - test_fd, pagesize * 3); - - /* Make sure we get pages aligned with the pagesize. - The target expects this. */ - fail_unless (p1 == (void *)addr); - fail_unless (p2 == (void *)addr + pagesize); - fail_unless (p3 == (void *)addr + pagesize * 2); - fail_unless (p4 == (void *)addr + pagesize * 3); - - /* Verify that the file maps was made correctly. */ - fail_unless (*p1 == 0); - fail_unless (*p2 == (pagesize / sizeof *p2)); - fail_unless (*p3 == ((pagesize * 2) / sizeof *p3)); - fail_unless (*p4 == ((pagesize * 3) / sizeof *p4)); - - memcpy (dummybuf, p1, pagesize); - memcpy (dummybuf, p2, pagesize); - memcpy (dummybuf, p3, pagesize); - memcpy (dummybuf, p4, pagesize); - - munmap (p1, pagesize); - munmap (p2, pagesize); - munmap (p3, pagesize); - munmap (p4, pagesize); - addr += pagesize * 4; - } - fprintf (stderr, " passed\n"); -} - -void checked_write(int fd, const void *buf, size_t count) -{ - ssize_t rc = write(fd, buf, count); - fail_unless(rc == count); -} - -int main(int argc, char **argv) -{ - char tempname[] = "/tmp/.cmmapXXXXXX"; - unsigned int i; - - /* Trust the first argument, otherwise probe the system for our - pagesize. */ - if (argc > 1) - pagesize = strtoul(argv[1], NULL, 0); - else - pagesize = sysconf(_SC_PAGESIZE); - - /* Assume pagesize is a power of two. */ - pagemask = pagesize - 1; - dummybuf = malloc (pagesize); - printf ("pagesize=%u pagemask=%x\n", pagesize, pagemask); - - test_fd = mkstemp(tempname); - unlink(tempname); - - /* Fill the file with int's counting from zero and up. */ - for (i = 0; i < (pagesize * 4) / sizeof i; i++) { - checked_write(test_fd, &i, sizeof i); - } - - /* Append a few extra writes to make the file end at non - page boundary. */ - checked_write(test_fd, &i, sizeof i); i++; - checked_write(test_fd, &i, sizeof i); i++; - checked_write(test_fd, &i, sizeof i); i++; - - test_fsize = lseek(test_fd, 0, SEEK_CUR); - - /* Run the tests. */ - check_aligned_anonymous_unfixed_mmaps(); - check_aligned_anonymous_unfixed_colliding_mmaps(); - check_aligned_anonymous_fixed_mmaps(); - check_file_unfixed_mmaps(); - check_file_fixed_mmaps(); - check_file_fixed_eof_mmaps(); - check_file_unfixed_eof_mmaps(); - - /* Fails at the moment. */ - /* check_aligned_anonymous_fixed_mmaps_collide_with_host(); */ - - return EXIT_SUCCESS; -} diff --git a/tests/tcg/test_path.c b/tests/tcg/test_path.c deleted file mode 100644 index 1c29bce..0000000 --- a/tests/tcg/test_path.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Test path override code */ -#include "config-host.h" -#include "util/cutils.c" -#include "util/hexdump.c" -#include "util/iov.c" -#include "util/path.c" -#include "util/qemu-timer-common.c" -#include -#include -#include - -void qemu_log(const char *fmt, ...); - -/* Any log message kills the test. */ -void qemu_log(const char *fmt, ...) -{ - va_list ap; - - fprintf(stderr, "FATAL: "); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - exit(1); -} - -#define NO_CHANGE(_path) \ - do { \ - if (strcmp(path(_path), _path) != 0) return __LINE__; \ - } while(0) - -#define CHANGE_TO(_path, _newpath) \ - do { \ - if (strcmp(path(_path), _newpath) != 0) return __LINE__; \ - } while(0) - -static void cleanup(void) -{ - unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE"); - unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE2"); - unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE3"); - unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE4"); - unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE5"); - rmdir("/tmp/qemu-test_path/DIR1/DIR2"); - rmdir("/tmp/qemu-test_path/DIR1/DIR3"); - rmdir("/tmp/qemu-test_path/DIR1"); - rmdir("/tmp/qemu-test_path"); -} - -static unsigned int do_test(void) -{ - if (mkdir("/tmp/qemu-test_path", 0700) != 0) - return __LINE__; - - if (mkdir("/tmp/qemu-test_path/DIR1", 0700) != 0) - return __LINE__; - - if (mkdir("/tmp/qemu-test_path/DIR1/DIR2", 0700) != 0) - return __LINE__; - - if (mkdir("/tmp/qemu-test_path/DIR1/DIR3", 0700) != 0) - return __LINE__; - - if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE", 0600)) != 0) - return __LINE__; - - if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE2", 0600)) != 0) - return __LINE__; - - if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE3", 0600)) != 0) - return __LINE__; - - if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE4", 0600)) != 0) - return __LINE__; - - if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE5", 0600)) != 0) - return __LINE__; - - init_paths("/tmp/qemu-test_path"); - - NO_CHANGE("/tmp"); - NO_CHANGE("/tmp/"); - NO_CHANGE("/tmp/qemu-test_path"); - NO_CHANGE("/tmp/qemu-test_path/"); - NO_CHANGE("/tmp/qemu-test_path/D"); - NO_CHANGE("/tmp/qemu-test_path/DI"); - NO_CHANGE("/tmp/qemu-test_path/DIR"); - NO_CHANGE("/tmp/qemu-test_path/DIR1"); - NO_CHANGE("/tmp/qemu-test_path/DIR1/"); - - NO_CHANGE("/D"); - NO_CHANGE("/DI"); - NO_CHANGE("/DIR"); - NO_CHANGE("/DIR2"); - NO_CHANGE("/DIR1."); - - CHANGE_TO("/DIR1", "/tmp/qemu-test_path/DIR1"); - CHANGE_TO("/DIR1/", "/tmp/qemu-test_path/DIR1"); - - NO_CHANGE("/DIR1/D"); - NO_CHANGE("/DIR1/DI"); - NO_CHANGE("/DIR1/DIR"); - NO_CHANGE("/DIR1/DIR1"); - - CHANGE_TO("/DIR1/DIR2", "/tmp/qemu-test_path/DIR1/DIR2"); - CHANGE_TO("/DIR1/DIR2/", "/tmp/qemu-test_path/DIR1/DIR2"); - - CHANGE_TO("/DIR1/DIR3", "/tmp/qemu-test_path/DIR1/DIR3"); - CHANGE_TO("/DIR1/DIR3/", "/tmp/qemu-test_path/DIR1/DIR3"); - - NO_CHANGE("/DIR1/DIR2/F"); - NO_CHANGE("/DIR1/DIR2/FI"); - NO_CHANGE("/DIR1/DIR2/FIL"); - NO_CHANGE("/DIR1/DIR2/FIL."); - - CHANGE_TO("/DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/DIR1/DIR2/FILE2", "/tmp/qemu-test_path/DIR1/DIR2/FILE2"); - CHANGE_TO("/DIR1/DIR2/FILE3", "/tmp/qemu-test_path/DIR1/DIR2/FILE3"); - CHANGE_TO("/DIR1/DIR2/FILE4", "/tmp/qemu-test_path/DIR1/DIR2/FILE4"); - CHANGE_TO("/DIR1/DIR2/FILE5", "/tmp/qemu-test_path/DIR1/DIR2/FILE5"); - - NO_CHANGE("/DIR1/DIR2/FILE6"); - NO_CHANGE("/DIR1/DIR2/FILE/X"); - - CHANGE_TO("/DIR1/../DIR1", "/tmp/qemu-test_path/DIR1"); - CHANGE_TO("/DIR1/../DIR1/", "/tmp/qemu-test_path/DIR1"); - CHANGE_TO("/../DIR1", "/tmp/qemu-test_path/DIR1"); - CHANGE_TO("/../DIR1/", "/tmp/qemu-test_path/DIR1"); - CHANGE_TO("/DIR1/DIR2/../DIR2", "/tmp/qemu-test_path/DIR1/DIR2"); - CHANGE_TO("/DIR1/DIR2/../DIR2/../../DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/DIR1/DIR2/../DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - - NO_CHANGE("/DIR1/DIR2/../DIR1"); - NO_CHANGE("/DIR1/DIR2/../FILE"); - - CHANGE_TO("/./DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/././DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/DIR1/./DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/DIR1/././DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/DIR1/DIR2/./FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/DIR1/DIR2/././FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/./DIR1/./DIR2/./FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - - return 0; -} - -int main(int argc, char *argv[]) -{ - int ret; - - ret = do_test(); - cleanup(); - if (ret) { - fprintf(stderr, "test_path: failed on line %i\n", ret); - return 1; - } - return 0; -} diff --git a/tests/tcg/testthread.c b/tests/tcg/testthread.c deleted file mode 100644 index 810ba5d..0000000 --- a/tests/tcg/testthread.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void checked_write(int fd, const void *buf, size_t count) -{ - ssize_t rc = write(fd, buf, count); - assert(rc == count); -} - -void *thread1_func(void *arg) -{ - int i; - char buf[512]; - - for(i=0;i<10;i++) { - snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg); - checked_write(1, buf, strlen(buf)); - usleep(100 * 1000); - } - return NULL; -} - -void *thread2_func(void *arg) -{ - int i; - char buf[512]; - for(i=0;i<20;i++) { - snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg); - checked_write(1, buf, strlen(buf)); - usleep(150 * 1000); - } - return NULL; -} - -void test_pthread(void) -{ - pthread_t tid1, tid2; - - pthread_create(&tid1, NULL, thread1_func, "hello1"); - pthread_create(&tid2, NULL, thread2_func, "hello2"); - pthread_join(tid1, NULL); - pthread_join(tid2, NULL); - printf("End of pthread test.\n"); -} - -int main(int argc, char **argv) -{ - test_pthread(); - return 0; -} -- cgit v1.1