diff options
Diffstat (limited to 'sim/testsuite/cris/c')
137 files changed, 4159 insertions, 0 deletions
diff --git a/sim/testsuite/cris/c/access1.c b/sim/testsuite/cris/c/access1.c new file mode 100644 index 0000000..ba9be34 --- /dev/null +++ b/sim/testsuite/cris/c/access1.c @@ -0,0 +1,16 @@ +/* Check access(2) trivially. Newlib doesn't have it. +#notarget: cris*-*-elf +*/ +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +int main (int argc, char **argv) +{ + if (access (argv[0], R_OK|W_OK|X_OK) == 0 + && access ("/dev/null", R_OK|W_OK) == 0 + && access ("/dev/null", X_OK) == -1 + && errno == EACCES) + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/append1.c b/sim/testsuite/cris/c/append1.c new file mode 100644 index 0000000..0acd59d --- /dev/null +++ b/sim/testsuite/cris/c/append1.c @@ -0,0 +1,51 @@ +/* Check regression of a bug uncovered by the libio tFile test (old + libstdc++, pre-gcc-3.x era), where appending to a file doesn't work. + The default open-flags-mapping does not match Linux/CRIS, so a + specific mapping is necessary. */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int +main (void) +{ + FILE *f; + const char fname[] = "sk1test.dat"; + const char tsttxt1[] + = "This is the first and only line of this file.\n"; + const char tsttxt2[] = "Now there is a second line.\n"; + char buf[sizeof (tsttxt1) + sizeof (tsttxt2) - 1] = ""; + + f = fopen (fname, "w+"); + if (f == NULL + || fwrite (tsttxt1, 1, strlen (tsttxt1), f) != strlen (tsttxt1) + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + f = fopen (fname, "a+"); + if (f == NULL + || fwrite (tsttxt2, 1, strlen (tsttxt2), f) != strlen (tsttxt2) + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + f = fopen (fname, "r"); + if (f == NULL + || fread (buf, 1, sizeof (buf), f) != sizeof (buf) - 1 + || strncmp (buf, tsttxt1, strlen (tsttxt1)) != 0 + || strncmp (buf + strlen (tsttxt1), tsttxt2, strlen (tsttxt2)) != 0 + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/badldso1.c b/sim/testsuite/cris/c/badldso1.c new file mode 100644 index 0000000..58caa8d --- /dev/null +++ b/sim/testsuite/cris/c/badldso1.c @@ -0,0 +1,7 @@ +/* +#notarget: cris*-*-elf +#dynamic: +#xerror: +#output: *: could not load ELF interpreter `*' for program `*'\n + */ +#include "hello.c" diff --git a/sim/testsuite/cris/c/badldso2.c b/sim/testsuite/cris/c/badldso2.c new file mode 100644 index 0000000..db28889 --- /dev/null +++ b/sim/testsuite/cris/c/badldso2.c @@ -0,0 +1,8 @@ +/* +#notarget: cris*-*-elf +#dynamic: +#xerror: +#cc: additional_flags=-Wl,-dynamic-linker,/dev/null +#output: *: could not load ELF interpreter `*' for program `*'\n + */ +#include "hello.c" diff --git a/sim/testsuite/cris/c/badldso3.c b/sim/testsuite/cris/c/badldso3.c new file mode 100644 index 0000000..3f9509b --- /dev/null +++ b/sim/testsuite/cris/c/badldso3.c @@ -0,0 +1,9 @@ +/* +#notarget: cris*-*-elf +#dynamic: +#xerror: +#cc: additional_flags=-Wl,-dynamic-linker,/compilercheck.x +#sim: --sysroot=@exedir@ +#output: *: could not load ELF interpreter `*' for program `*'\n + */ +#include "hello.c" diff --git a/sim/testsuite/cris/c/c.exp b/sim/testsuite/cris/c/c.exp new file mode 100644 index 0000000..08ea188 --- /dev/null +++ b/sim/testsuite/cris/c/c.exp @@ -0,0 +1,253 @@ +# Copyright (C) 2005-2021 Free Software Foundation, Inc. +# +# 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/>. + +# Miscellaneous CRIS simulator testcases testing syscall sequences. + +if ![istarget cris*-*-*] { + return +} + +set CFLAGS_FOR_TARGET "-O2" +if [istarget cris-*-*] { + set mach "crisv10" +} { + set mach "crisv32" +} + +if [istarget cris*-*-elf] { + append CFLAGS_FOR_TARGET " -sim" +} + +# Using target_compile, since it is less noisy, +if { [target_compile $srcdir/$subdir/hello.c compilercheck.x \ + "executable" "" ] == "" } { + set has_cc 1 + + # Now check if we can link a program dynamically, and where + # libc.so is located. If it is, we provide a sym link to the + # directory (which must end in /lib) in [pwd], so /lib/ld.so.1 is + # found (which must reside along libc.so). We don't bother + # replacing the board ldflags like below as we don't care about + # detrimental effects on the executable from the specs and + # -static in the board ldflags, we just add -Bdynamic. + if [regexp "(.*/lib)/libc.so" \ + [target_compile $srcdir/$subdir/hello.c compilercheck.x \ + "executable" \ + "ldflags=-print-file-name=libc.so -Wl,-Bdynamic"] \ + xxx libcsodir] { + file delete lib + verbose -log "Creating link to $libcsodir in [pwd]" + file link lib $libcsodir + } +} { + verbose -log "Can't execute C compiler" + set has_cc 0 +} + +# Like istarget, except take a list of targets as a string. +proc anytarget { targets } { + set targetlist [split $targets] + set argc [llength $targetlist] + for { set i 0 } { $i < $argc } { incr i } { + if [istarget [lindex $targetlist $i]] { + return 1 + } + } + return 0 +} + +foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.c]] { + set orig_ldflags "" + + if ![runtest_file_p $runtests $src] { + continue + } + set testname "[file tail $src]" + + set opt_array [slurp_options $src] + if { $opt_array == -1 } { + unresolved $testname + return + } + + # And again, to simplify specifying tests. + if ![runtest_file_p $runtests $src] { + continue + } + + # Note absence of CC in results, but don't make a big fuss over it. + if { $has_cc == 0 } { + untested $testname + continue + } + + # Clear default options + set opts(cc) "" + set opts(sim) "" + set opts(output) "" + set opts(progoptions) "" + set opts(timeout) "" + set opts(mach) "" + set opts(xerror) "no" + set opts(dest) "$testname.x" + set opts(simenv) "" + set opts(kfail) "" + set opts(xfail) "" + set opts(target) "" + set opts(notarget) "" + set opts(dynamic) "" + + # Clear any machine specific options specified in a previous test case + if [info exists opts(sim,$mach)] { + unset opts(sim,$mach) + } + + foreach i $opt_array { + set opt_name [lindex $i 0] + set opt_machs [lindex $i 1] + set opt_val [lindex $i 2] + if ![info exists opts($opt_name)] { + perror "unknown option $opt_name in file $src" + unresolved $testname + return + } + + # Replace specific substitutions: + # @exedir@ is where the test-program is located. + regsub -all "@exedir@" $opt_val "[pwd]" opt_val + # @srcdir@ is where the source of the test-program is located. + regsub -all "@srcdir@" $opt_val "$srcdir/$subdir" opt_val + + # Multiple of these options concatenate, they don't override. + if { $opt_name == "output" || $opt_name == "progoptions" } { + set opt_val "$opts($opt_name)$opt_val" + } + + # Similar with "xfail", "kfail", "target" and "notarget", but + # arguments are space-separated. + if { $opt_name == "xfail" || $opt_name == "kfail" \ + || $opt_name == "target" || $opt_name == "notarget" } { + if { $opts($opt_name) != "" } { + set opt_val "$opts($opt_name) $opt_val" + } + } + + if { $opt_name == "dynamic" \ + && [info exists board_info([target_info name],ldflags)] } { + # Weed out -static from ldflags, but keep the original in + # $orig_ldflags. + set orig_ldflags $board_info([target_info name],ldflags) + set ldflags " $orig_ldflags " + regsub -all " -static " $ldflags " " ldflags + set board_info([target_info name],ldflags) $ldflags + } + + foreach m $opt_machs { + set opts($opt_name,$m) $opt_val + } + if { "$opt_machs" == "" } { + set opts($opt_name) $opt_val + } + } + + if { $opts(output) == "" } { + if { "$opts(xerror)" == "no" } { + set opts(output) "pass\n" + } else { + set opts(output) "fail\n" + } + } + + if { $opts(target) != "" && ![anytarget $opts(target)] } { + continue + } + + if { $opts(notarget) != "" && [anytarget $opts(notarget)] } { + continue + } + + # If no machine specific options, default to the general version. + if ![info exists opts(sim,$mach)] { + set opts(sim,$mach) $opts(sim) + } + + # Change \n sequences to newline chars. + regsub -all "\\\\n" $opts(output) "\n" opts(output) + + verbose -log "Compiling $src with $opts(cc)" + + set dest "$opts(dest)" + if { [sim_compile $src $dest "executable" "$opts(cc)" ] != "" } { + unresolved $testname + continue + } + + if { $orig_ldflags != "" } { + set board_info([target_info name],ldflags) $orig_ldflags + } + + verbose -log "Simulating $src with $opts(sim,$mach)" + + # Time to setup xfailures and kfailures. + if { "$opts(xfail)" != "" } { + verbose -log "xfail: $opts(xfail)" + # Using eval to make $opts(xfail) appear as individual + # arguments. + eval setup_xfail $opts(xfail) + } + if { "$opts(kfail)" != "" } { + verbose -log "kfail: $opts(kfail)" + eval setup_kfail $opts(kfail) + } + + set result [sim_run $dest "$opts(sim,$mach)" "$opts(progoptions)" \ + "" "$opts(simenv)"] + set return_code [lindex $result 0] + set output [lindex $result 1] + + set status fail + if { $return_code == 0 } { + set status pass + } + + if { "$status" == "pass" } { + if { "$opts(xerror)" == "no" } { + if [string match $opts(output) $output] { + pass "$mach $testname" + } else { + verbose -log "output: $output" 3 + verbose -log "pattern: $opts(output)" 3 + fail "$mach $testname (execution)" + } + } else { + verbose -log "`pass' return code when expecting failure" 3 + fail "$mach $testname (execution)" + } + } elseif { "$status" == "fail" } { + if { "$opts(xerror)" == "no" } { + fail "$mach $testname (execution)" + } else { + if [string match $opts(output) $output] { + pass "$mach $testname" + } else { + verbose -log "output: $output" 3 + verbose -log "pattern: $opts(output)" 3 + fail "$mach $testname (execution)" + } + } + } else { + $status "$mach $testname" + } +} diff --git a/sim/testsuite/cris/c/clone1.c b/sim/testsuite/cris/c/clone1.c new file mode 100644 index 0000000..163b186 --- /dev/null +++ b/sim/testsuite/cris/c/clone1.c @@ -0,0 +1,90 @@ +/* +#notarget: cris*-*-elf +#output: got: a\nthen: bc\nexit: 0\n +*/ + +/* This is a very limited subset of what ex1.c does; we just check that + thread creation (clone syscall) and pipe writes and reads work. */ + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sched.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/wait.h> + +int pip[2]; + +int +process (void *arg) +{ + char *s = arg; + if (write (pip[1], s+2, 1) != 1) abort (); + if (write (pip[1], s+1, 1) != 1) abort (); + if (write (pip[1], s, 1) != 1) abort (); + return 0; +} + +int +main (void) +{ + int retcode; + int pid; + int st; + long stack[16384]; + char buf[10] = {0}; + + retcode = pipe (pip); + + if (retcode != 0) + { + fprintf (stderr, "Bad pipe %d\n", retcode); + abort (); + } + + pid = clone (process, (char *) stack + sizeof (stack) - 64, + (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND) + | SIGCHLD, "cba"); + if (pid <= 0) + { + fprintf (stderr, "Bad clone %d\n", pid); + abort (); + } + + if ((retcode = read (pip[0], buf, 1)) != 1) + { + fprintf (stderr, "Bad read 1: %d\n", retcode); + abort (); + } + printf ("got: %c\n", buf[0]); + retcode = read (pip[0], buf, 2); + if (retcode == 1) + { + retcode = read (pip[0], buf+1, 1); + if (retcode != 1) + { + fprintf (stderr, "Bad read 1.5: %d\n", retcode); + abort (); + } + retcode = 2; + } + if (retcode != 2) + { + fprintf (stderr, "Bad read 2: %d\n", retcode); + abort (); + } + + printf ("then: %s\n", buf); + retcode = wait4 (-1, &st, WNOHANG | __WCLONE, NULL); + + if (retcode != pid || !WIFEXITED (st)) + { + fprintf (stderr, "Bad wait %d %x\n", retcode, st); + abort (); + } + + printf ("exit: %d\n", WEXITSTATUS (st)); + return 0; +} diff --git a/sim/testsuite/cris/c/clone2.c b/sim/testsuite/cris/c/clone2.c new file mode 100644 index 0000000..e433a77 --- /dev/null +++ b/sim/testsuite/cris/c/clone2.c @@ -0,0 +1,6 @@ +/* Make sure the thread system trivially works with trace output. +#notarget: cris*-*-elf +#sim: --cris-trace=basic --trace-file=@exedir@/clone2.tmp +#output: got: a\nthen: bc\nexit: 0\n +*/ +#include "clone1.c" diff --git a/sim/testsuite/cris/c/clone3.c b/sim/testsuite/cris/c/clone3.c new file mode 100644 index 0000000..0a97484 --- /dev/null +++ b/sim/testsuite/cris/c/clone3.c @@ -0,0 +1,45 @@ +/* Check that exiting from a parent thread does not kill the child. +#notarget: cris*-*-elf +*/ + +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> +#include <unistd.h> +#include <sched.h> +#include <signal.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/wait.h> + +int +process (void *arg) +{ + int i; + + for (i = 0; i < 50; i++) + if (sched_yield ()) + abort (); + + printf ("pass\n"); + return 0; +} + +int +main (void) +{ + int pid; + long stack[16384]; + + pid = clone (process, (char *) stack + sizeof (stack) - 64, + (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND) + | SIGCHLD, "ab"); + if (pid <= 0) + { + fprintf (stderr, "Bad clone %d\n", pid); + abort (); + } + + exit (0); +} diff --git a/sim/testsuite/cris/c/clone4.c b/sim/testsuite/cris/c/clone4.c new file mode 100644 index 0000000..81489dd --- /dev/null +++ b/sim/testsuite/cris/c/clone4.c @@ -0,0 +1,61 @@ +/* Check that TRT happens when we reach the #threads implementation limit. +#notarget: cris*-*-elf +*/ + +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> +#include <unistd.h> +#include <sched.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/wait.h> + +int +process (void *arg) +{ + int i; + + for (i = 0; i < 500; i++) + if (sched_yield ()) + abort (); + + return 0; +} + +int +main (void) +{ + int pid; + int i; + int stacksize = 16384; + + for (i = 0; i < 1000; i++) + { + char *stack = malloc (stacksize); + if (stack == NULL) + abort (); + + pid = clone (process, (char *) stack + stacksize - 64, + (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND) + | SIGCHLD, "ab"); + if (pid <= 0) + { + /* FIXME: Read sysconf instead of magic number. */ + if (i < 60) + { + fprintf (stderr, "Bad clone %d\n", pid); + abort (); + } + + if (errno == EAGAIN) + { + printf ("pass\n"); + exit (0); + } + } + } + + abort (); +} diff --git a/sim/testsuite/cris/c/clone5.c b/sim/testsuite/cris/c/clone5.c new file mode 100644 index 0000000..9380a1e --- /dev/null +++ b/sim/testsuite/cris/c/clone5.c @@ -0,0 +1,35 @@ +/* Check that unimplemented clone syscalls get the right treatment. +#notarget: cris*-*-elf +#xerror: +#output: Unimplemented clone syscall * +#output: program stopped with signal 4 (*).\n +*/ + +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> + +int pip[2]; + +int +process (void *arg) +{ + return 0; +} + +int +main (void) +{ + int retcode; + long stack[16384]; + + retcode = clone (process, (char *) stack + sizeof (stack) - 64, 0, "cba"); + if (retcode == -1 && errno == ENOSYS) + printf ("ENOSYS\n"); + printf ("xyzzy\n"); + return 0; +} diff --git a/sim/testsuite/cris/c/clone6.c b/sim/testsuite/cris/c/clone6.c new file mode 100644 index 0000000..586b5c6 --- /dev/null +++ b/sim/testsuite/cris/c/clone6.c @@ -0,0 +1,8 @@ +/* As the included file, but specifying silent ENOSYS. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=enosys-quiet +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "clone5.c" diff --git a/sim/testsuite/cris/c/ex1.c b/sim/testsuite/cris/c/ex1.c new file mode 100644 index 0000000..2447319 --- /dev/null +++ b/sim/testsuite/cris/c/ex1.c @@ -0,0 +1,54 @@ +/* Compiler options: +#notarget: cris*-*-elf +#cc: additional_flags=-pthread +#output: Starting process a\naaaaaaaaStarting process b\nababbbbbbbbb + + The output will change depending on the exact syscall sequence per + thread, so will change with glibc versions. Prepare to modify; use + the latest glibc. + + This file is from glibc/linuxthreads, with the difference that the + number is 10, not 10000. */ + +/* Creates two threads, one printing 10000 "a"s, the other printing + 10000 "b"s. + Illustrates: thread creation, thread joining. */ + +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> +#include "pthread.h" + +static void * +process (void *arg) +{ + int i; + fprintf (stderr, "Starting process %s\n", (char *) arg); + for (i = 0; i < 10; i++) + { + write (1, (char *) arg, 1); + } + return NULL; +} + +int +main (void) +{ + int retcode; + pthread_t th_a, th_b; + void *retval; + + retcode = pthread_create (&th_a, NULL, process, (void *) "a"); + if (retcode != 0) + fprintf (stderr, "create a failed %d\n", retcode); + retcode = pthread_create (&th_b, NULL, process, (void *) "b"); + if (retcode != 0) + fprintf (stderr, "create b failed %d\n", retcode); + retcode = pthread_join (th_a, &retval); + if (retcode != 0) + fprintf (stderr, "join a failed %d\n", retcode); + retcode = pthread_join (th_b, &retval); + if (retcode != 0) + fprintf (stderr, "join b failed %d\n", retcode); + return 0; +} diff --git a/sim/testsuite/cris/c/exitg1.c b/sim/testsuite/cris/c/exitg1.c new file mode 100644 index 0000000..0b4c425 --- /dev/null +++ b/sim/testsuite/cris/c/exitg1.c @@ -0,0 +1,20 @@ +/* Check exit_group(2) trivially. Newlib doesn't have it and the + pre-v32 glibc requires updated headers we'd have to check or adjust + for. +#notarget: cris-*-* *-*-elf +#output: exit_group\n +*/ +#include <unistd.h> +#include <sys/syscall.h> +#include <stdio.h> +#include <stdlib.h> +#ifndef EXITVAL +#define EXITVAL 0 +#endif +int main (int argc, char **argv) +{ + printf ("exit_group\n"); + syscall (SYS_exit_group, EXITVAL); + printf ("failed\n"); + abort (); +} diff --git a/sim/testsuite/cris/c/exitg2.c b/sim/testsuite/cris/c/exitg2.c new file mode 100644 index 0000000..e222cc4 --- /dev/null +++ b/sim/testsuite/cris/c/exitg2.c @@ -0,0 +1,7 @@ +/* Check exit_group(2) trivially with non-zero status. +#notarget: cris-*-* *-*-elf +#output: exit_group\n +#xerror: +*/ +#define EXITVAL 1 +#include "exitg1.c" diff --git a/sim/testsuite/cris/c/fcntl1.c b/sim/testsuite/cris/c/fcntl1.c new file mode 100644 index 0000000..032f6b5 --- /dev/null +++ b/sim/testsuite/cris/c/fcntl1.c @@ -0,0 +1,19 @@ +/* Check that we get the expected message for unsupported fcntl calls. +#notarget: cris*-*-elf +#xerror: +#output: Unimplemented fcntl* +#output: program stopped with signal 4 (*).\n +*/ +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> + +int main (void) +{ + int err = fcntl (1, 42); + if (err == -1 && errno == ENOSYS) + printf ("ENOSYS\n"); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/fcntl2.c b/sim/testsuite/cris/c/fcntl2.c new file mode 100644 index 0000000..fc9f95b --- /dev/null +++ b/sim/testsuite/cris/c/fcntl2.c @@ -0,0 +1,8 @@ +/* As the included file, but specifying silent ENOSYS. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=enosys-quiet +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "fcntl1.c" diff --git a/sim/testsuite/cris/c/fdopen1.c b/sim/testsuite/cris/c/fdopen1.c new file mode 100644 index 0000000..cdfe19a --- /dev/null +++ b/sim/testsuite/cris/c/fdopen1.c @@ -0,0 +1,54 @@ +/* Check that the syscalls implementing fdopen work trivially. */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <fcntl.h> + +void +perr (const char *s) +{ + perror (s); + exit (1); +} + +int +main (void) +{ + FILE *f; + int fd; + const char fname[] = "sk1test.dat"; + const char tsttxt1[] + = "This is the first and only line of this file.\n"; + char buf[sizeof (tsttxt1)] = ""; + + fd = open (fname, O_WRONLY|O_TRUNC|O_CREAT, S_IRWXU); + if (fd <= 0) + perr ("open-w"); + + f = fdopen (fd, "w"); + if (f == NULL + || fwrite (tsttxt1, 1, strlen (tsttxt1), f) != strlen (tsttxt1)) + perr ("fdopen or fwrite"); + + if (fclose (f) != 0) + perr ("fclose"); + + fd = open (fname, O_RDONLY); + if (fd <= 0) + perr ("open-r"); + + f = fdopen (fd, "r"); + if (f == NULL + || fread (buf, 1, sizeof (buf), f) != strlen (tsttxt1) + || strcmp (buf, tsttxt1) != 0 + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/fdopen2.c b/sim/testsuite/cris/c/fdopen2.c new file mode 100644 index 0000000..6a59f36 --- /dev/null +++ b/sim/testsuite/cris/c/fdopen2.c @@ -0,0 +1,52 @@ +/* Check that the syscalls implementing fdopen work trivially. +#output: This is the first line of this test.\npass\n +*/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <fcntl.h> + +void +perr (const char *s) +{ + perror (s); + exit (1); +} + +int +main (void) +{ + FILE *f; + int fd; + const char fname[] = "sk1test.dat"; + const char tsttxt1[] + = "This is the first line of this test.\n"; + char buf[sizeof (tsttxt1)] = ""; + + /* Write a line to stdout. */ + f = fdopen (1, "w"); + if (f == NULL + || fwrite (tsttxt1, 1, strlen (tsttxt1), f) != strlen (tsttxt1)) + perr ("fdopen or fwrite"); + +#if 0 + /* Unfortunately we can't get < /dev/null to the simulator with + reasonable test-framework surgery. */ + + /* Try to read from stdin. Expect EOF. */ + f = fdopen (0, "r"); + if (f == NULL + || fread (buf, 1, sizeof (buf), f) != 0 + || feof (f) == 0 + || ferror (f) != 0) + { + printf ("fail\n"); + exit (1); + } +#endif + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/freopen1.c b/sim/testsuite/cris/c/freopen1.c new file mode 100644 index 0000000..0e0f28d --- /dev/null +++ b/sim/testsuite/cris/c/freopen1.c @@ -0,0 +1,49 @@ +/* Check that basic freopen functionality works. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int +main (void) +{ + FILE *old_stderr; + FILE *f; + const char fname[] = "sk1test.dat"; + const char tsttxt[] + = "A random line of text, used to test correct freopen etc.\n"; + char buf[sizeof tsttxt] = ""; + + /* Like the freopen call in flex. */ + old_stderr = freopen (fname, "w+", stderr); + if (old_stderr == NULL + || fwrite (tsttxt, 1, strlen (tsttxt), stderr) != strlen (tsttxt) + || fclose (stderr) != 0) + { + printf ("fail\n"); + exit (1); + } + + /* Using "rb" to make this test similar to the use in genconf.c in + GhostScript. */ + f = fopen (fname, "rb"); + if (f == NULL + || fseek (f, 0L, SEEK_END) != 0 + || ftell (f) != strlen (tsttxt)) + { + printf ("fail\n"); + exit (1); + } + + rewind (f); + if (fread (buf, 1, strlen (tsttxt), f) != strlen (tsttxt) + || strcmp (buf, tsttxt) != 0 + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/freopen2.c b/sim/testsuite/cris/c/freopen2.c new file mode 100644 index 0000000..3959607 --- /dev/null +++ b/sim/testsuite/cris/c/freopen2.c @@ -0,0 +1,40 @@ +/* Tests that stdin can be redirected from a normal file. */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int +main (void) +{ + const char* fname = "freopen.dat"; + const char tsttxt[] + = "A random line of text, used to test correct freopen etc.\n"; + FILE* instream; + FILE *old_stderr; + char c1; + + /* Like the freopen call in flex. */ + old_stderr = freopen (fname, "w+", stderr); + if (old_stderr == NULL + || fwrite (tsttxt, 1, strlen (tsttxt), stderr) != strlen (tsttxt) + || fclose (stderr) != 0) + { + printf ("fail\n"); + exit (1); + } + + instream = freopen(fname, "r", stdin); + if (instream == NULL) { + printf("fail\n"); + exit(1); + } + + c1 = getc(instream); + if (c1 != 'A') { + printf("fail\n"); + exit(1); + } + + printf ("pass\n"); + exit(0); +} diff --git a/sim/testsuite/cris/c/ftruncate1.c b/sim/testsuite/cris/c/ftruncate1.c new file mode 100644 index 0000000..46b8756 --- /dev/null +++ b/sim/testsuite/cris/c/ftruncate1.c @@ -0,0 +1,52 @@ +/* Check that the ftruncate syscall works trivially. +#notarget: cris*-*-elf +*/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +void +perr (const char *s) +{ + perror (s); + exit (1); +} + +int +main (void) +{ + FILE *f; + const char fname[] = "sk1test.dat"; + const char tsttxt1[] + = "This is the first and only line of this file.\n"; + const char tsttxt2[] = "Now there is a second line.\n"; + char buf[sizeof (tsttxt1) + sizeof (tsttxt2) - 1] = ""; + + f = fopen (fname, "w+"); + if (f == NULL + || fwrite (tsttxt1, 1, strlen (tsttxt1), f) != strlen (tsttxt1)) + perr ("open or fwrite"); + + if (fflush (f) != 0) + perr ("fflush"); + + if (ftruncate (fileno (f), strlen(tsttxt1) - 20) != 0) + perr ("ftruncate"); + + if (fclose (f) != 0) + perr ("fclose"); + + f = fopen (fname, "r"); + if (f == NULL + || fread (buf, 1, sizeof (buf), f) != strlen (tsttxt1) - 20 + || strncmp (buf, tsttxt1, strlen (tsttxt1) - 20) != 0 + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/ftruncate2.c b/sim/testsuite/cris/c/ftruncate2.c new file mode 100644 index 0000000..f1ef18c --- /dev/null +++ b/sim/testsuite/cris/c/ftruncate2.c @@ -0,0 +1,39 @@ +/* +#notarget: cris*-*-elf +*/ + +/* Check that we get a proper error indication if trying ftruncate on a + fd that is a pipe descriptor. */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> +int main (void) +{ + int pip[2]; + + if (pipe (pip) != 0) + { + perror ("pipe"); + abort (); + } + + if (ftruncate (pip[0], 20) == 0 || errno != EINVAL) + { + perror ("ftruncate 1"); + abort (); + } + + errno = 0; + + if (ftruncate (pip[1], 20) == 0 || errno != EINVAL) + { + perror ("ftruncate 2"); + abort (); + } + + printf ("pass\n"); + + exit (0); +} diff --git a/sim/testsuite/cris/c/getcwd1.c b/sim/testsuite/cris/c/getcwd1.c new file mode 100644 index 0000000..3838916 --- /dev/null +++ b/sim/testsuite/cris/c/getcwd1.c @@ -0,0 +1,18 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) +{ + if (getcwd ((void *) -1, 4096) != NULL + || errno != EFAULT) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/gettod.c b/sim/testsuite/cris/c/gettod.c new file mode 100644 index 0000000..18a000c --- /dev/null +++ b/sim/testsuite/cris/c/gettod.c @@ -0,0 +1,27 @@ +/* Basic time functionality test. */ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <sys/time.h> +int +main (void) +{ + struct timeval t_m = {0, 0}; + time_t t; + + if ((t = time (NULL)) == (time_t) -1 + || gettimeofday (&t_m, NULL) != 0 + || t_m.tv_sec == 0 + + /* We assume there will be no delay between the time and + gettimeofday calls above, but allow a timer-tick to make the + seconds increase by one. */ + || (t != t_m.tv_sec && t+1 != t_m.tv_sec)) + { + printf ("fail\n"); + exit (1); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/hello.c b/sim/testsuite/cris/c/hello.c new file mode 100644 index 0000000..fb403ba --- /dev/null +++ b/sim/testsuite/cris/c/hello.c @@ -0,0 +1,7 @@ +#include <stdio.h> +#include <stdlib.h> +int main () +{ + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/helloaout.c b/sim/testsuite/cris/c/helloaout.c new file mode 100644 index 0000000..c71a658 --- /dev/null +++ b/sim/testsuite/cris/c/helloaout.c @@ -0,0 +1,14 @@ +/* Make sure we don't just assume ELF all over. (We have to jump + through hoops to get runnable a.out out of the ELF setup, and + having problems with a.out and discontinous section arrangements + doesn't help. Adjust as needed to get a.out which says "pass". If + necessary, move to the asm subdir. By design, it doesn't work with + CRIS v32.) + +NB: We'd rely on kfail, but that doesn't skip compilation, and that's where +the crash in ld happens to break the testcase. +#target: disabled-cris-*-elf +#kfail: ld/13900 cris-*-elf +#cc: ldflags=-Wl,-mcrisaout\ -sim\ -Ttext=0 +*/ +#include "hello.c" diff --git a/sim/testsuite/cris/c/hellodyn.c b/sim/testsuite/cris/c/hellodyn.c new file mode 100644 index 0000000..dc8042f --- /dev/null +++ b/sim/testsuite/cris/c/hellodyn.c @@ -0,0 +1,5 @@ +/* +#dynamic: +#sim: --sysroot=@exedir@ + */ +#include "hello.c" diff --git a/sim/testsuite/cris/c/hellodyn2.c b/sim/testsuite/cris/c/hellodyn2.c new file mode 100644 index 0000000..00f5369 --- /dev/null +++ b/sim/testsuite/cris/c/hellodyn2.c @@ -0,0 +1,5 @@ +/* +#dynamic: +#sim: --sysroot=@exedir@ --load-vma + */ +#include "hello.c" diff --git a/sim/testsuite/cris/c/hellodyn3.c b/sim/testsuite/cris/c/hellodyn3.c new file mode 100644 index 0000000..8ae3a4f --- /dev/null +++ b/sim/testsuite/cris/c/hellodyn3.c @@ -0,0 +1,9 @@ +/* Check that invoking ld.so as a program, invoking the main program, + works. Jump through a few hoops to avoid reading the host + ld.so.cache (having no absolute path specified for the executable + falls back on loading through the same mechanisms as a DSO). +#notarget: *-*-elf +#dynamic: +#sim: --sysroot=@exedir@ @exedir@/lib/ld.so.1 --library-path / + */ +#include "hello.c" diff --git a/sim/testsuite/cris/c/kill1.c b/sim/testsuite/cris/c/kill1.c new file mode 100644 index 0000000..e5c53a0 --- /dev/null +++ b/sim/testsuite/cris/c/kill1.c @@ -0,0 +1,30 @@ +/* Basic kill functionality test; fail killing init. Don't run as root. */ +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <signal.h> +int +main (void) +{ + if (kill (1, SIGTERM) != -1 + || errno != EPERM) + { + printf ("fail\n"); + exit (1); + } + + errno = 0; + + if (kill (1, SIGABRT) != -1 + || errno != EPERM) + { + printf ("fail\n"); + exit (1); + } + + errno = 0; + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/kill2.c b/sim/testsuite/cris/c/kill2.c new file mode 100644 index 0000000..0a79db0 --- /dev/null +++ b/sim/testsuite/cris/c/kill2.c @@ -0,0 +1,18 @@ +/* Basic kill functionality test; suicide. +#xerror: +#output: program stopped with signal 6 (*).\n +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <signal.h> +#include <unistd.h> + +int +main (void) +{ + kill (getpid (), SIGABRT); + printf ("undead\n"); + exit (1); +} diff --git a/sim/testsuite/cris/c/kill3.c b/sim/testsuite/cris/c/kill3.c new file mode 100644 index 0000000..c0e2179 --- /dev/null +++ b/sim/testsuite/cris/c/kill3.c @@ -0,0 +1,16 @@ +/* Basic kill functionality test; suicide. +#xerror: +#output: program stopped with signal 6 (*).\n +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <signal.h> +int +main (void) +{ + abort (); + printf ("undead\n"); + exit (1); +} diff --git a/sim/testsuite/cris/c/mapbrk.c b/sim/testsuite/cris/c/mapbrk.c new file mode 100644 index 0000000..1aff762 --- /dev/null +++ b/sim/testsuite/cris/c/mapbrk.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <stdlib.h> + +/* Basic sanity check that syscalls to implement malloc (brk, mmap2, + munmap) are trivially functional. */ + +int main () +{ + void *p1, *p2, *p3, *p4, *p5, *p6; + + if ((p1 = malloc (8100)) == NULL + || (p2 = malloc (16300)) == NULL + || (p3 = malloc (4000)) == NULL + || (p4 = malloc (500)) == NULL + || (p5 = malloc (1023*1024)) == NULL + || (p6 = malloc (8191*1024)) == NULL) + { + printf ("fail\n"); + exit (1); + } + + free (p1); + free (p2); + free (p3); + free (p4); + free (p5); + free (p6); + + p1 = malloc (64000); + if (p1 == NULL) + { + printf ("fail\n"); + exit (1); + } + free (p1); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/mmap1.c b/sim/testsuite/cris/c/mmap1.c new file mode 100644 index 0000000..9db94c1 --- /dev/null +++ b/sim/testsuite/cris/c/mmap1.c @@ -0,0 +1,52 @@ +/* +#notarget: cris*-*-elf +*/ + +#define _GNU_SOURCE +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> + +int main (int argc, char *argv[]) +{ + int fd = open (argv[0], O_RDONLY); + struct stat sb; + int size; + void *a; + const char *str = "a string you'll only find in the program"; + + if (fd == -1) + { + perror ("open"); + abort (); + } + + if (fstat (fd, &sb) < 0) + { + perror ("fstat"); + abort (); + } + + size = sb.st_size; + + /* We want to test mmapping a size that isn't exactly a page. */ + if ((size & 8191) == 0) + size--; + +#ifndef MMAP_FLAGS +#define MMAP_FLAGS MAP_PRIVATE +#endif + + a = mmap (NULL, size, PROT_READ, MMAP_FLAGS, fd, 0); + + if (memmem (a, size, str, strlen (str) + 1) == NULL) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/mmap2.c b/sim/testsuite/cris/c/mmap2.c new file mode 100644 index 0000000..35139a0 --- /dev/null +++ b/sim/testsuite/cris/c/mmap2.c @@ -0,0 +1,48 @@ +/* +#notarget: cris*-*-elf +*/ + +#define _GNU_SOURCE +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> + +int main (int argc, char *argv[]) +{ + int fd = open (argv[0], O_RDONLY); + struct stat sb; + int size; + void *a; + const char *str = "a string you'll only find in the program"; + + if (fd == -1) + { + perror ("open"); + abort (); + } + + if (fstat (fd, &sb) < 0) + { + perror ("fstat"); + abort (); + } + + size = sb.st_size; + + /* We want to test mmapping a size that isn't exactly a page. */ + if ((size & 8191) == 0) + size--; + + a = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0); + + if (memmem (a, size, str, strlen (str) + 1) == NULL) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/mmap3.c b/sim/testsuite/cris/c/mmap3.c new file mode 100644 index 0000000..34401fa --- /dev/null +++ b/sim/testsuite/cris/c/mmap3.c @@ -0,0 +1,33 @@ +/* +#notarget: cris*-*-elf +*/ + +#define _GNU_SOURCE +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <sys/mman.h> + +int main (int argc, char *argv[]) +{ + volatile unsigned char *a; + + /* Check that we can map a non-multiple of a page and still get a full page. */ + a = mmap (NULL, 0x4c, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (a == NULL || a == (unsigned char *) -1) + abort (); + + a[0] = 0xbe; + a[8191] = 0xef; + memset ((char *) a + 1, 0, 8190); + + if (a[0] != 0xbe || a[8191] != 0xef) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/mmap4.c b/sim/testsuite/cris/c/mmap4.c new file mode 100644 index 0000000..b3a66e4 --- /dev/null +++ b/sim/testsuite/cris/c/mmap4.c @@ -0,0 +1,5 @@ +/* Just check that MAP_DENYWRITE is "honored" (ignored). +#notarget: cris*-*-elf +*/ +#define MMAP_FLAGS (MAP_PRIVATE|MAP_DENYWRITE) +#include "mmap1.c" diff --git a/sim/testsuite/cris/c/mmap5.c b/sim/testsuite/cris/c/mmap5.c new file mode 100644 index 0000000..95f00c3 --- /dev/null +++ b/sim/testsuite/cris/c/mmap5.c @@ -0,0 +1,91 @@ +/* +#notarget: cris*-*-elf +*/ + +#define _GNU_SOURCE +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> + +int main (int argc, char *argv[]) +{ + int fd = open (argv[0], O_RDONLY); + struct stat sb; + int size; + void *a; + void *b; + const char *str = "a string you'll only find in the program"; + + if (fd == -1) + { + perror ("open"); + abort (); + } + + if (fstat (fd, &sb) < 0) + { + perror ("fstat"); + abort (); + } + + size = 8192; +#ifdef MMAP_SIZE1 + size = MMAP_SIZE1; +#endif + +#ifndef MMAP_PROT1 +#define MMAP_PROT1 PROT_READ | PROT_WRITE | PROT_EXEC +#endif + +#ifndef MMAP_FLAGS1 +#define MMAP_FLAGS1 MAP_PRIVATE | MAP_ANONYMOUS +#endif + + /* Get a page, any page. */ + b = mmap (NULL, size, MMAP_PROT1, MMAP_FLAGS1, -1, 0); + if (b == MAP_FAILED) + abort (); + + /* Remember it, unmap it. */ +#ifndef NO_MUNMAP + if (munmap (b, size) != 0) + abort (); +#endif + +#ifdef MMAP_ADDR2 + b = MMAP_ADDR2; +#endif + +#ifndef MMAP_PROT2 +#define MMAP_PROT2 PROT_READ | PROT_EXEC +#endif + +#ifndef MMAP_FLAGS2 +#define MMAP_FLAGS2 MAP_DENYWRITE | MAP_FIXED | MAP_PRIVATE +#endif + + size = sb.st_size; +#ifdef MMAP_SIZE2 + size = MMAP_SIZE2; +#endif + +#define MMAP_TEST_BAD_ORIG \ + (a == MAP_FAILED || memmem (a, size, str, strlen (str) + 1) == NULL) +#ifndef MMAP_TEST_BAD +#define MMAP_TEST_BAD MMAP_TEST_BAD_ORIG +#endif + + /* Try mapping the now non-mapped page fixed. */ + a = mmap (b, size, MMAP_PROT2, MMAP_FLAGS2, fd, 0); + + if (MMAP_TEST_BAD) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/mmap6.c b/sim/testsuite/cris/c/mmap6.c new file mode 100644 index 0000000..929d9cc --- /dev/null +++ b/sim/testsuite/cris/c/mmap6.c @@ -0,0 +1,8 @@ +/* Check that mmapping specifying a previously mmapped address without + MAP_FIXED works; that we just don't get the same address. +#notarget: cris*-*-elf +*/ +#define NO_MUNMAP +#define MMAP_FLAGS2 MAP_PRIVATE +#define MMAP_TEST_BAD (a == b || MMAP_TEST_BAD_ORIG) +#include "mmap5.c" diff --git a/sim/testsuite/cris/c/mmap7.c b/sim/testsuite/cris/c/mmap7.c new file mode 100644 index 0000000..c4b14b0 --- /dev/null +++ b/sim/testsuite/cris/c/mmap7.c @@ -0,0 +1,14 @@ +/* Check that mmapping a page-aligned size, larger than the file, + works. + +#notarget: cris*-*-elf +*/ + +/* Make sure we get an address where the size fits. */ +#define MMAP_SIZE1 ((sb.st_size + 8192) & ~8191) + +/* If this ever fails because the file is a page-multiple, we'll deal + with that then. We want it larger than the file-size anyway. */ +#define MMAP_SIZE2 ((size + 8192) & ~8191) +#define MMAP_FLAGS2 MAP_DENYWRITE | MAP_PRIVATE | MAP_FIXED +#include "mmap5.c" diff --git a/sim/testsuite/cris/c/mmap8.c b/sim/testsuite/cris/c/mmap8.c new file mode 100644 index 0000000..0564c79 --- /dev/null +++ b/sim/testsuite/cris/c/mmap8.c @@ -0,0 +1,9 @@ +/* Check that mmapping 0 using MAP_FIXED works, both with/without + there being previously mmapped contents. +#notarget: cris*-*-elf +*/ +#define MMAP_FLAGS1 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED +#define NO_MUNMAP +#define MMAP_SIZE2 8192 +#define MMAP_TEST_BAD (a != b || a != 0) +#include "mmap5.c" diff --git a/sim/testsuite/cris/c/mprotect1.c b/sim/testsuite/cris/c/mprotect1.c new file mode 100644 index 0000000..8dae50b --- /dev/null +++ b/sim/testsuite/cris/c/mprotect1.c @@ -0,0 +1,19 @@ +/* Check unimplemented-output for mprotect call. +#notarget: cris*-*-elf +#xerror: +#output: Unimplemented mprotect call (0x0, 0x2001, 0x4)\n +#output: program stopped with signal 4 (*).\n + */ +#include <stdlib.h> +#include <stdio.h> +#include <sys/mman.h> +#include <errno.h> + +int main (int argc, char *argv[]) +{ + int err = mprotect (0, 8193, PROT_EXEC); + if (err == -1 && errno == ENOSYS) + printf ("ENOSYS\n"); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/mprotect2.c b/sim/testsuite/cris/c/mprotect2.c new file mode 100644 index 0000000..4d83945 --- /dev/null +++ b/sim/testsuite/cris/c/mprotect2.c @@ -0,0 +1,8 @@ +/* As the included file, but specifying silent ENOSYS. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=enosys-quiet +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "mprotect1.c" diff --git a/sim/testsuite/cris/c/mremap.c b/sim/testsuite/cris/c/mremap.c new file mode 100644 index 0000000..e78a8a4 --- /dev/null +++ b/sim/testsuite/cris/c/mremap.c @@ -0,0 +1,31 @@ +#include <stdio.h> +#include <stdlib.h> + +/* Sanity check that system calls for realloc works. Also tests a few + more cases for mmap2 and munmap. */ + +int main () +{ + void *p1, *p2; + + if ((p1 = malloc (8100)) == NULL + || (p1 = realloc (p1, 16300)) == NULL + || (p1 = realloc (p1, 4000)) == NULL + || (p1 = realloc (p1, 500)) == NULL + || (p1 = realloc (p1, 1023*1024)) == NULL + || (p1 = realloc (p1, 8191*1024)) == NULL + || (p1 = realloc (p1, 512*1024)) == NULL + || (p2 = malloc (1023*1024)) == NULL + || (p1 = realloc (p1, 1023*1024)) == NULL + || (p1 = realloc (p1, 8191*1024)) == NULL + || (p1 = realloc (p1, 512*1024)) == NULL) + { + printf ("fail\n"); + exit (1); + } + + free (p1); + free (p2); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/openpf1.c b/sim/testsuite/cris/c/openpf1.c new file mode 100644 index 0000000..e0d8e5c --- /dev/null +++ b/sim/testsuite/cris/c/openpf1.c @@ -0,0 +1,38 @@ +/* Check that --sysroot is applied to open(2). +#sim: --sysroot=@exedir@ + + We assume, with EXE being the name of the executable: + - The simulator executes with cwd the same directory where the executable + is located (so argv[0] contains a plain filename without directory + components). + - There's no /EXE on the host file system. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +int main (int argc, char *argv[]) +{ + char *fnam = argv[0]; + FILE *f; + if (argv[0][0] != '/') + { + fnam = malloc (strlen (argv[0]) + 2); + if (fnam == NULL) + abort (); + strcpy (fnam, "/"); + strcat (fnam, argv[0]); + } + + f = fopen (fnam, "rb"); + if (f == NULL) + abort (); + fclose (f); + + /* Cover another execution path. */ + if (fopen ("/nonexistent", "rb") != NULL + || errno != ENOENT) + abort (); + printf ("pass\n"); + return 0; +} diff --git a/sim/testsuite/cris/c/openpf2.c b/sim/testsuite/cris/c/openpf2.c new file mode 100644 index 0000000..50337b1 --- /dev/null +++ b/sim/testsuite/cris/c/openpf2.c @@ -0,0 +1,16 @@ +/* Check that the simulator has chdir:ed to the --sysroot argument +#sim: --sysroot=@srcdir@ + (or that --sysroot is applied to relative file paths). */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +int main (int argc, char *argv[]) +{ + FILE *f = fopen ("openpf2.c", "rb"); + if (f == NULL) + abort (); + fclose (f); + printf ("pass\n"); + return 0; +} diff --git a/sim/testsuite/cris/c/openpf3.c b/sim/testsuite/cris/c/openpf3.c new file mode 100644 index 0000000..557adee --- /dev/null +++ b/sim/testsuite/cris/c/openpf3.c @@ -0,0 +1,49 @@ +/* Basic file operations (rename, unlink); once without sysroot. We + also test that the simulator has chdir:ed to PREFIX, when defined. */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#ifndef PREFIX +#define PREFIX +#endif + +void err (const char *s) +{ + perror (s); + abort (); +} + +int main (int argc, char *argv[]) +{ + FILE *f; + struct stat buf; + + unlink (PREFIX "testfoo2.tmp"); + + f = fopen ("testfoo1.tmp", "w"); + if (f == NULL) + err ("open"); + fclose (f); + + if (rename (PREFIX "testfoo1.tmp", PREFIX "testfoo2.tmp") != 0) + err ("rename"); + + if (stat (PREFIX "testfoo2.tmp", &buf) != 0 + || !S_ISREG (buf.st_mode)) + err ("stat 1"); + + if (stat ("testfoo2.tmp", &buf) != 0 + || !S_ISREG (buf.st_mode)) + err ("stat 2"); + + if (unlink (PREFIX "testfoo2.tmp") != 0) + err ("unlink"); + + printf ("pass\n"); + return 0; +} diff --git a/sim/testsuite/cris/c/openpf4.c b/sim/testsuite/cris/c/openpf4.c new file mode 100644 index 0000000..d3fdcfe --- /dev/null +++ b/sim/testsuite/cris/c/openpf4.c @@ -0,0 +1,5 @@ +/* Basic file operations, now *with* sysroot. +#sim: --sysroot=@exedir@ +*/ +#define PREFIX "/" +#include "openpf3.c" diff --git a/sim/testsuite/cris/c/openpf5.c b/sim/testsuite/cris/c/openpf5.c new file mode 100644 index 0000000..1f86ea2 --- /dev/null +++ b/sim/testsuite/cris/c/openpf5.c @@ -0,0 +1,56 @@ +/* Check that TRT happens when error on too many opened files. +#notarget: cris*-*-elf +#sim: --sysroot=@exedir@ +*/ +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> + +int main (int argc, char *argv[]) +{ + int i; + int filemax; + +#ifdef OPEN_MAX + filemax = OPEN_MAX; +#else + filemax = sysconf (_SC_OPEN_MAX); +#endif + + char *fn = malloc (strlen (argv[0]) + 2); + if (fn == NULL) + abort (); + strcpy (fn, "/"); + strcat (fn, argv[0]); + + for (i = 0; i < filemax + 1; i++) + { + if (open (fn, O_RDONLY) < 0) + { + /* Shouldn't happen too early. */ + if (i < filemax - 3 - 1) + { + fprintf (stderr, "i: %d\n", i); + abort (); + } + if (errno != EMFILE) + { + perror ("open"); + abort (); + } + goto ok; + } + } + abort (); + +ok: + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/pipe1.c b/sim/testsuite/cris/c/pipe1.c new file mode 100644 index 0000000..735974b --- /dev/null +++ b/sim/testsuite/cris/c/pipe1.c @@ -0,0 +1,48 @@ +/* Check for proper pipe semantics at corner cases. +#notarget: cris*-*-elf +*/ + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sched.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <limits.h> +#include <unistd.h> + +int main (void) +{ + int i; + int filemax; + +#ifdef OPEN_MAX + filemax = OPEN_MAX; +#else + filemax = sysconf (_SC_OPEN_MAX); +#endif + + if (filemax < 10) + abort (); + + /* Check that pipes don't leak file descriptors. */ + for (i = 0; i < filemax * 10; i++) + { + int pip[2]; + if (pipe (pip) != 0) + { + perror ("pipe"); + abort (); + } + + if (close (pip[0]) != 0 || close (pip[1]) != 0) + { + perror ("close"); + abort (); + } + } + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/pipe2.c b/sim/testsuite/cris/c/pipe2.c new file mode 100644 index 0000000..18ccf38 --- /dev/null +++ b/sim/testsuite/cris/c/pipe2.c @@ -0,0 +1,143 @@ +/* Check that closing a pipe with a nonempty buffer works. +#notarget: cris*-*-elf +#output: got: a\ngot: b\nexit: 0\n +*/ + + +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> +#include <unistd.h> +#include <sched.h> +#include <signal.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <string.h> +int pip[2]; + +int pipemax; + +int +process (void *arg) +{ + char *s = arg; + int lots = pipemax + 256; + char *buf = malloc (lots); + int ret; + + if (buf == NULL) + abort (); + + *buf = *s; + + /* The first write should go straight through. */ + if (write (pip[1], buf, 1) != 1) + abort (); + + *buf = s[1]; + + /* The second write may or may not be successful for the whole + write, but should be successful for at least the pipemax part. + As linux/limits.h clamps PIPE_BUF to 4096, but the page size is + actually 8k, we can get away with that much. There should be no + error, though. Doing this on host shows that for + x86_64-unknown-linux-gnu (2.6.14-1.1656_FC4) pipemax * 10 can be + successfully written, perhaps for similar reasons. */ + ret = write (pip[1], buf, lots); + if (ret < pipemax) + { + fprintf (stderr, "ret: %d, %s, %d\n", ret, strerror (errno), pipemax); + fflush (0); + abort (); + } + + return 0; +} + +int +main (void) +{ + int retcode; + int pid; + int st = 0; + long stack[16384]; + char buf[1]; + + /* We need to turn this off because we don't want (to have to model) a + SIGPIPE resulting from the close. */ + if (signal (SIGPIPE, SIG_IGN) != SIG_DFL) + abort (); + + retcode = pipe (pip); + + if (retcode != 0) + { + fprintf (stderr, "Bad pipe %d\n", retcode); + abort (); + } + +#ifdef PIPE_MAX + pipemax = PIPE_MAX; +#else + pipemax = fpathconf (pip[1], _PC_PIPE_BUF); +#endif + + if (pipemax <= 0) + { + fprintf (stderr, "Bad pipemax %d\n", pipemax); + abort (); + } + + pid = clone (process, (char *) stack + sizeof (stack) - 64, + (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND) + | SIGCHLD, "ab"); + if (pid <= 0) + { + fprintf (stderr, "Bad clone %d\n", pid); + abort (); + } + + while ((retcode = read (pip[0], buf, 1)) == 0) + ; + + if (retcode != 1) + { + fprintf (stderr, "Bad read 1: %d\n", retcode); + abort (); + } + + printf ("got: %c\n", buf[0]); + + /* Need to read out something from the second write too before + closing, or the writer can get EPIPE. */ + while ((retcode = read (pip[0], buf, 1)) == 0) + ; + + if (retcode != 1) + { + fprintf (stderr, "Bad read 2: %d\n", retcode); + abort (); + } + + printf ("got: %c\n", buf[0]); + + if (close (pip[0]) != 0) + { + perror ("pip close"); + abort (); + } + + retcode = waitpid (pid, &st, __WALL); + + if (retcode != pid || !WIFEXITED (st)) + { + fprintf (stderr, "Bad wait %d:%d %x\n", pid, retcode, st); + perror ("errno"); + abort (); + } + + printf ("exit: %d\n", WEXITSTATUS (st)); + return 0; +} diff --git a/sim/testsuite/cris/c/pipe3.c b/sim/testsuite/cris/c/pipe3.c new file mode 100644 index 0000000..bf08a38 --- /dev/null +++ b/sim/testsuite/cris/c/pipe3.c @@ -0,0 +1,48 @@ +/* Check that TRT happens when error on pipe call. +#notarget: cris*-*-elf +*/ + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <limits.h> + +int main (void) +{ + int i; + int filemax; + +#ifdef OPEN_MAX + filemax = OPEN_MAX; +#else + filemax = sysconf (_SC_OPEN_MAX); +#endif + + /* Check that TRT happens when error on pipe call. */ + for (i = 0; i < filemax + 1; i++) + { + int pip[2]; + if (pipe (pip) != 0) + { + /* Shouldn't happen too early. */ + if (i < filemax / 2 - 3 - 1) + { + fprintf (stderr, "i: %d\n", i); + abort (); + } + if (errno != EMFILE) + { + perror ("pipe"); + abort (); + } + goto ok; + } + } + abort (); + +ok: + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/pipe4.c b/sim/testsuite/cris/c/pipe4.c new file mode 100644 index 0000000..1cb309f --- /dev/null +++ b/sim/testsuite/cris/c/pipe4.c @@ -0,0 +1,66 @@ +/* Check that TRT happens for pipe corner cases. +#notarget: cris*-*-elf +*/ +#include <stddef.h> +#include <signal.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <limits.h> + +void err (const char *s) +{ + perror (s); + abort (); +} + +int main (void) +{ + int pip[2]; + char c; + int pipemax; + + if (pipe (pip) != 0) + err ("pipe"); + +#ifdef PIPE_MAX + pipemax = PIPE_MAX; +#else + pipemax = fpathconf (pip[1], _PC_PIPE_BUF); +#endif + + if (pipemax <= 0) + { + fprintf (stderr, "Bad pipemax %d\n", pipemax); + abort (); + } + + /* Writing to wrong end of pipe. */ + if (write (pip[0], "argh", 1) != -1 + || errno != EBADF) + err ("write pipe"); + + errno = 0; + + /* Reading from wrong end of pipe. */ + if (read (pip[1], &c, 1) != -1 + || errno != EBADF) + err ("write pipe"); + + errno = 0; + + if (close (pip[0]) != 0) + err ("close"); + + if (signal (SIGPIPE, SIG_IGN) != SIG_DFL) + err ("signal"); + + /* Writing to pipe with closed read end. */ + if (write (pip[1], "argh", 1) != -1 + || errno != EPIPE) + err ("write closed"); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/pipe5.c b/sim/testsuite/cris/c/pipe5.c new file mode 100644 index 0000000..2b4d763 --- /dev/null +++ b/sim/testsuite/cris/c/pipe5.c @@ -0,0 +1,59 @@ +/* Check that TRT happens for pipe corner cases (for our definition of TRT). +#notarget: cris*-*-elf +#xerror: +#output: Terminating simulation due to writing pipe * from one single thread\n +#output: program stopped with signal 4 (*).\n +*/ +#include <stddef.h> +#include <signal.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <limits.h> + +void err (const char *s) +{ + perror (s); + abort (); +} + +int main (void) +{ + int pip[2]; + int pipemax; + char *buf; + + if (pipe (pip) != 0) + err ("pipe"); + +#ifdef PIPE_MAX + pipemax = PIPE_MAX; +#else + pipemax = fpathconf (pip[1], _PC_PIPE_BUF); +#endif + + if (pipemax <= 0) + { + fprintf (stderr, "Bad pipemax %d\n", pipemax); + abort (); + } + + /* Writing an inordinate amount to the pipe. */ + buf = calloc (100 * pipemax, 1); + if (buf == NULL) + err ("calloc"); + + /* The following doesn't trig on host; writing more than PIPE_MAX to a + pipe with no reader makes the program hang. Neither does it trig + on target: we don't want to emulate the "hanging" (which would + happen with *any* amount written to a pipe with no reader if we'd + support it - but we don't). Better to abort the simulation with a + suitable message. */ + if (write (pip[1], buf, 100 * pipemax) != -1 + || errno != EFBIG) + err ("write mucho"); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/pipe6.c b/sim/testsuite/cris/c/pipe6.c new file mode 100644 index 0000000..a8830cc --- /dev/null +++ b/sim/testsuite/cris/c/pipe6.c @@ -0,0 +1,111 @@ +/* Check that writing an inordinate amount of data works (somewhat). +#notarget: cris*-*-elf +#output: got: a\nexit: 0\n + This test-case will *not* work on host (or for real): the first + pipemax+1 bytes will be successfully written. It's just for + exercising a rare execution path. */ + +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> +#include <unistd.h> +#include <sched.h> +#include <signal.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/wait.h> + +int pip[2]; + +int pipemax; + +int +process (void *arg) +{ + char *s = arg; + char *buf = calloc (pipemax * 100, 1); + int ret; + + if (buf == NULL) + abort (); + + *buf = *s; + + ret = write (pip[1], buf, pipemax * 100); + if (ret != -1 || errno != EFBIG) + { + perror ("write"); + abort (); + } + + return 0; +} + +int +main (void) +{ + int retcode; + int pid; + int st = 0; + long stack[16384]; + char buf[1]; + + retcode = pipe (pip); + + if (retcode != 0) + { + fprintf (stderr, "Bad pipe %d\n", retcode); + abort (); + } + +#ifdef PIPE_MAX + pipemax = PIPE_MAX; +#else + pipemax = fpathconf (pip[1], _PC_PIPE_BUF); +#endif + + if (pipemax <= 0) + { + fprintf (stderr, "Bad pipemax %d\n", pipemax); + abort (); + } + + pid = clone (process, (char *) stack + sizeof (stack) - 64, + (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND) + | SIGCHLD, "ab"); + if (pid <= 0) + { + fprintf (stderr, "Bad clone %d\n", pid); + abort (); + } + + while ((retcode = read (pip[0], buf, 1)) == 0) + ; + + if (retcode != 1) + { + fprintf (stderr, "Bad read 1: %d\n", retcode); + abort (); + } + + printf ("got: %c\n", buf[0]); + + if (close (pip[0]) != 0) + { + perror ("pip close"); + abort (); + } + + retcode = waitpid (pid, &st, __WALL); + + if (retcode != pid || !WIFEXITED (st)) + { + fprintf (stderr, "Bad wait %d:%d %x\n", pid, retcode, st); + perror ("errno"); + abort (); + } + + printf ("exit: %d\n", WEXITSTATUS (st)); + return 0; +} diff --git a/sim/testsuite/cris/c/pipe7.c b/sim/testsuite/cris/c/pipe7.c new file mode 100644 index 0000000..552ddb8 --- /dev/null +++ b/sim/testsuite/cris/c/pipe7.c @@ -0,0 +1,21 @@ +/* Check for proper pipe semantics at corner cases. +#notarget: cris*-*-elf +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> + +int main (void) +{ + if (pipe (NULL) != -1 + || errno != EFAULT) + { + perror ("pipe"); + abort (); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/readlink1.c b/sim/testsuite/cris/c/readlink1.c new file mode 100644 index 0000000..1898e8e --- /dev/null +++ b/sim/testsuite/cris/c/readlink1.c @@ -0,0 +1,20 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) +{ + char buf[1024]; + /* This depends on the test-setup, but it's unlikely that the program + is passed as a symlink, so supposedly safe. */ + if (readlink(argv[0], buf, sizeof (buf)) != -1 || errno != EINVAL) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/readlink10.c b/sim/testsuite/cris/c/readlink10.c new file mode 100644 index 0000000..2174408 --- /dev/null +++ b/sim/testsuite/cris/c/readlink10.c @@ -0,0 +1,18 @@ +/* Check that odd cases of readlink work. +#notarget: cris*-*-elf +*/ + +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) +{ + if (readlink("/proc/42/exe", NULL, 4096) != -1 + || errno != EFAULT) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/readlink11.c b/sim/testsuite/cris/c/readlink11.c new file mode 100644 index 0000000..05a332f --- /dev/null +++ b/sim/testsuite/cris/c/readlink11.c @@ -0,0 +1,9 @@ +/* As readlink5.c (sic), but specifying silent ENOSYS. +#notarget: cris*-*-elf +#dest: ./readlink11.c.x +#sim: --cris-unknown-syscall=enosys-quiet +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "readlink2.c" diff --git a/sim/testsuite/cris/c/readlink2.c b/sim/testsuite/cris/c/readlink2.c new file mode 100644 index 0000000..e5e9d94 --- /dev/null +++ b/sim/testsuite/cris/c/readlink2.c @@ -0,0 +1,80 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int main (int argc, char *argv[]) +{ + char buf[1024]; + char buf2[1024]; + int err; + + /* This is a special feature handled in the simulator. The "42" + should be formed from getpid () if this was a real program. */ + err = readlink ("/proc/42/exe", buf, sizeof (buf)); + if (err < 0) + { + if (err == -1 && errno == ENOSYS) + printf ("ENOSYS\n"); + printf ("xyzzy\n"); + exit (0); + } + + /* Don't use an abort in the following; it might cause the printf to + not make it all the way to output and make debugging more + difficult. */ + + /* We assume the program is called with no path, so we might need to + prepend it. */ + if (getcwd (buf2, sizeof (buf2)) != buf2) + { + perror ("getcwd"); + exit (1); + } + + if (argv[0][0] == '/') + { +#ifdef SYSROOTED + if (strchr (argv[0] + 1, '/') != NULL) + { + printf ("%s != %s\n", argv[0], strrchr (argv[0] + 1, '/')); + exit (1); + } +#endif + if (strcmp (argv[0], buf) != 0) + { + printf ("%s != %s\n", buf, argv[0]); + exit (1); + } + } + else if (argv[0][0] != '.') + { + if (buf2[strlen (buf2) - 1] != '/') + strcat (buf2, "/"); + strcat (buf2, argv[0]); + if (strcmp (buf2, buf) != 0) + { + printf ("%s != %s\n", buf, buf2); + exit (1); + } + } + else + { + strcat (buf2, argv[0] + 1); + if (strcmp (buf, buf2) != 0) + { + printf ("%s != %s\n", buf, buf2); + exit (1); + } + } + + printf ("pass\n"); + exit (0); +} + + diff --git a/sim/testsuite/cris/c/readlink3.c b/sim/testsuite/cris/c/readlink3.c new file mode 100644 index 0000000..94cff72 --- /dev/null +++ b/sim/testsuite/cris/c/readlink3.c @@ -0,0 +1,6 @@ +/* Simulator options: +#notarget: cris*-*-elf +#sim: --sysroot=@exedir@ +*/ +#define SYSROOTED 1 +#include "readlink2.c" diff --git a/sim/testsuite/cris/c/readlink4.c b/sim/testsuite/cris/c/readlink4.c new file mode 100644 index 0000000..028f3ee --- /dev/null +++ b/sim/testsuite/cris/c/readlink4.c @@ -0,0 +1,62 @@ +/* Check for corner case: readlink of too-long name. +#notarget: cris*-*-elf +*/ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <stdarg.h> + +void bye (const char *s, int i) +{ + fprintf (stderr, "%s: %d\n", s, i); + fflush (NULL); + abort (); +} + +int main (int argc, char *argv[]) +{ + char *buf; + char buf2[1024]; + int max, i; + + /* We assume this limit is what we see in the simulator as well. */ +#ifdef PATH_MAX + max = PATH_MAX; +#else + max = pathconf (argv[0], _PC_PATH_MAX); +#endif + + max *= 10; + + if (max <= 0) + bye ("path_max", max); + + if ((buf = malloc (max + 1)) == NULL) + bye ("malloc", 0); + + strcat (buf, argv[0]); + + if (strrchr (buf, '/') == NULL) + strcat (buf, "./"); + + for (i = strrchr (buf, '/') - buf + 1; i < max; i++) + buf[i] = 'a'; + + buf [i] = 0; + + i = readlink (buf, buf2, sizeof (buf2) - 1); + if (i != -1) + bye ("i", i); + + if (errno != ENAMETOOLONG) + { + perror (buf); + bye ("errno", errno); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/readlink5.c b/sim/testsuite/cris/c/readlink5.c new file mode 100644 index 0000000..80f20da --- /dev/null +++ b/sim/testsuite/cris/c/readlink5.c @@ -0,0 +1,8 @@ +/* Check that unsupported readlink calls don't cause the simulator to abort. +#notarget: cris*-*-elf +#dest: ./readlink5.c.x +#xerror: +#output: Unimplemented readlink syscall (*)\n +#output: program stopped with signal 4 (*).\n +*/ +#include "readlink2.c" diff --git a/sim/testsuite/cris/c/readlink6.c b/sim/testsuite/cris/c/readlink6.c new file mode 100644 index 0000000..4bac20d --- /dev/null +++ b/sim/testsuite/cris/c/readlink6.c @@ -0,0 +1,5 @@ +/* Check that rare readlink calls don't cause the simulator to abort. +#notarget: cris*-*-elf +#dest: @exedir@/readlink6.c.x +*/ +#include "readlink2.c" diff --git a/sim/testsuite/cris/c/readlink7.c b/sim/testsuite/cris/c/readlink7.c new file mode 100644 index 0000000..9c2b3b7 --- /dev/null +++ b/sim/testsuite/cris/c/readlink7.c @@ -0,0 +1,6 @@ +/* Check that rare readlink calls don't cause the simulator to abort. +#notarget: cris*-*-elf +#simenv: env(-u\ PWD\ foo)=bar + FIXME: Need to unset PWD, but right now I won't bother tweaking the + generic parts of the testsuite machinery and instead abuse a flaw. */ +#include "readlink2.c" diff --git a/sim/testsuite/cris/c/readlink8.c b/sim/testsuite/cris/c/readlink8.c new file mode 100644 index 0000000..55f6fe8 --- /dev/null +++ b/sim/testsuite/cris/c/readlink8.c @@ -0,0 +1,8 @@ +/* Check that rare readlink calls don't cause the simulator to abort. +#notarget: cris*-*-elf +#sim: --sysroot=@exedir@ +#simenv: env(-u\ PWD\ foo)=bar + FIXME: Need to unset PWD, but right now I won't bother tweaking the + generic parts of the testsuite machinery and instead abuse a flaw. */ +#define SYSROOTED 1 +#include "readlink2.c" diff --git a/sim/testsuite/cris/c/readlink9.c b/sim/testsuite/cris/c/readlink9.c new file mode 100644 index 0000000..2788054 --- /dev/null +++ b/sim/testsuite/cris/c/readlink9.c @@ -0,0 +1,23 @@ +/* Check that odd cases of readlink work. +#notarget: cris*-*-elf +#cc: additional_flags=-DX="@exedir@" +*/ + +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) +{ + /* We assume that "sim/testsuite" isn't renamed to anything that + together with "<builddir>/" is shorter than 7 characters. */ + char buf[7]; + + if (readlink("/proc/42/exe", buf, sizeof (buf)) != sizeof (buf) + || strncmp (buf, X, sizeof (buf)) != 0) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/rename2.c b/sim/testsuite/cris/c/rename2.c new file mode 100644 index 0000000..39387d1 --- /dev/null +++ b/sim/testsuite/cris/c/rename2.c @@ -0,0 +1,38 @@ +/* Test some execution paths for error cases. +#cc: additional_flags=-Wl,--section-start=.startup=0x8000 + The linker option is for sake of newlib, where the default program + layout starts at address 0. We need to change the layout so + there's no memory at 0, as all sim error checking is "lazy", + depending on lack of memory mapping. */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> + +void err (const char *s) +{ + perror (s); + abort (); +} + +int main (int argc, char *argv[]) +{ + /* Avoid getting files with random characters due to errors + elsewhere. */ + if (argc != 1 + || (argv[0][0] != '.' && argv[0][0] != '/' && argv[0][0] != 'r')) + abort (); + + if (rename (argv[0], NULL) != -1 + || errno != EFAULT) + err ("rename 1 "); + + errno = 0; + + if (rename (NULL, argv[0]) != -1 + || errno != EFAULT) + err ("rename 2"); + + printf ("pass\n"); + return 0; +} diff --git a/sim/testsuite/cris/c/rtsigprocmask1.c b/sim/testsuite/cris/c/rtsigprocmask1.c new file mode 100644 index 0000000..b76c338 --- /dev/null +++ b/sim/testsuite/cris/c/rtsigprocmask1.c @@ -0,0 +1,51 @@ +/* Compiler options: +#notarget: cris*-*-elf +#cc: additional_flags=-pthread +#xerror: +#output: Unimplemented rt_sigprocmask syscall (0x3, 0x0, 0x3dff*\n +#output: program stopped with signal 4 (*).\n + + Testing a signal handler corner case. */ + +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <signal.h> +#include <pthread.h> +#include <errno.h> + +static void * +process (void *arg) +{ + while (1) + sched_yield (); + return NULL; +} + +int +main (void) +{ + int retcode; + pthread_t th_a; + void *retval; + sigset_t sigs; + + if (sigemptyset (&sigs) != 0) + abort (); + + retcode = pthread_create (&th_a, NULL, process, NULL); + if (retcode != 0) + abort (); + + /* An invalid parameter 1 should cause this to halt the simulator. */ + retcode + = pthread_sigmask (SIG_BLOCK + SIG_UNBLOCK + SIG_SETMASK, NULL, &sigs); + /* Direct return of the error number; i.e. not using -1 and errno, + is the actual documented behavior. */ + if (retcode == ENOSYS) + printf ("ENOSYS\n"); + + printf ("xyzzy\n"); + return 0; +} diff --git a/sim/testsuite/cris/c/rtsigprocmask2.c b/sim/testsuite/cris/c/rtsigprocmask2.c new file mode 100644 index 0000000..5026908 --- /dev/null +++ b/sim/testsuite/cris/c/rtsigprocmask2.c @@ -0,0 +1,9 @@ +/* As the included file, but specifying silent ENOSYS. +#notarget: cris*-*-elf +#cc: additional_flags=-pthread +#sim: --cris-unknown-syscall=enosys-quiet +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "rtsigprocmask1.c" diff --git a/sim/testsuite/cris/c/rtsigsuspend1.c b/sim/testsuite/cris/c/rtsigsuspend1.c new file mode 100644 index 0000000..66ca795 --- /dev/null +++ b/sim/testsuite/cris/c/rtsigsuspend1.c @@ -0,0 +1,21 @@ +/* Test that TRT happens for invalid rt_sigsuspend calls. Single-thread. +#notarget: cris*-*-elf +#xerror: +#output: Unimplemented rt_sigsuspend syscall arguments (0x1, 0x2)\n +#output: program stopped with signal 4 (*).\n +*/ + +#include <unistd.h> +#include <sys/syscall.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> + +int main (void) +{ + int err = syscall (SYS_rt_sigsuspend, 1, 2); + if (err == -1 && errno == ENOSYS) + printf ("ENOSYS\n"); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/rtsigsuspend2.c b/sim/testsuite/cris/c/rtsigsuspend2.c new file mode 100644 index 0000000..9ce165d --- /dev/null +++ b/sim/testsuite/cris/c/rtsigsuspend2.c @@ -0,0 +1,8 @@ +/* As the included file, but specifying silent ENOSYS. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=enosys-quiet +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "rtsigsuspend1.c" diff --git a/sim/testsuite/cris/c/sched1.c b/sim/testsuite/cris/c/sched1.c new file mode 100644 index 0000000..1b778f4 --- /dev/null +++ b/sim/testsuite/cris/c/sched1.c @@ -0,0 +1,16 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <sched.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +int main (void) +{ + if (sched_getscheduler (getpid ()) != SCHED_OTHER) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sched2.c b/sim/testsuite/cris/c/sched2.c new file mode 100644 index 0000000..f40a19a --- /dev/null +++ b/sim/testsuite/cris/c/sched2.c @@ -0,0 +1,20 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <sched.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int main (void) +{ + struct sched_param sb; + memset (&sb, -1, sizeof sb); + if (sched_getparam (getpid (), &sb) != 0 + || sb.sched_priority != 0) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sched3.c b/sim/testsuite/cris/c/sched3.c new file mode 100644 index 0000000..2909a4b --- /dev/null +++ b/sim/testsuite/cris/c/sched3.c @@ -0,0 +1,25 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <sched.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> + +int main (void) +{ + struct sched_param sb; + sb.sched_priority = 0; + if (sched_setscheduler (getpid (), SCHED_OTHER, &sb) != 0 + || sb.sched_priority != 0) + abort (); + sb.sched_priority = 5; + if (sched_setscheduler (getpid (), SCHED_OTHER, &sb) != -1 + || errno != EINVAL + || sb.sched_priority != 5) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sched4.c b/sim/testsuite/cris/c/sched4.c new file mode 100644 index 0000000..df372f2 --- /dev/null +++ b/sim/testsuite/cris/c/sched4.c @@ -0,0 +1,25 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <sched.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> + +int main (void) +{ + struct sched_param sb; + sb.sched_priority = 0; + if (sched_setparam (getpid (), &sb) != 0 + || sb.sched_priority != 0) + abort (); + sb.sched_priority = 5; + if (sched_setparam (getpid (), &sb) == 0 + || errno != EINVAL + || sb.sched_priority != 5) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sched5.c b/sim/testsuite/cris/c/sched5.c new file mode 100644 index 0000000..ddfe14d --- /dev/null +++ b/sim/testsuite/cris/c/sched5.c @@ -0,0 +1,19 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <sched.h> +#include <stdio.h> +#include <stdlib.h> +int main (void) +{ + int Min = sched_get_priority_min (SCHED_OTHER); + int Max = sched_get_priority_max (SCHED_OTHER); + if (Min != 0 || Max != 0) + { + fprintf (stderr, "min: %d, max: %d\n", Min, Max); + abort (); + } + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sched6.c b/sim/testsuite/cris/c/sched6.c new file mode 100644 index 0000000..d5adedc --- /dev/null +++ b/sim/testsuite/cris/c/sched6.c @@ -0,0 +1,15 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <sched.h> +#include <stdio.h> +#include <stdlib.h> + +int main (void) +{ + if (sched_yield () != 0) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sched7.c b/sim/testsuite/cris/c/sched7.c new file mode 100644 index 0000000..35d006b --- /dev/null +++ b/sim/testsuite/cris/c/sched7.c @@ -0,0 +1,17 @@ +/* Check corner error case: specifying invalid PID. +#notarget: cris*-*-elf +*/ + +#include <sched.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> + +int main (void) +{ + if (sched_getscheduler (99) != -1 + || errno != ESRCH) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sched8.c b/sim/testsuite/cris/c/sched8.c new file mode 100644 index 0000000..cd3e06e --- /dev/null +++ b/sim/testsuite/cris/c/sched8.c @@ -0,0 +1,19 @@ +/* Check corner error case: specifying invalid PID. +#notarget: cris*-*-elf +*/ +#include <string.h> +#include <sched.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> + +int main (void) +{ + struct sched_param sb; + memset (&sb, -1, sizeof sb); + if (sched_getparam (99, &sb) != -1 + || errno != ESRCH) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sched9.c b/sim/testsuite/cris/c/sched9.c new file mode 100644 index 0000000..8499e43 --- /dev/null +++ b/sim/testsuite/cris/c/sched9.c @@ -0,0 +1,24 @@ +/* Check corner error case: specifying invalid scheduling policy. +#notarget: cris*-*-elf +*/ + +#include <sched.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> + +int main (void) +{ + if (sched_get_priority_min (-1) != -1 + || errno != EINVAL) + abort (); + + errno = 0; + + if (sched_get_priority_max (-1) != -1 + || errno != EINVAL) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/seek1.c b/sim/testsuite/cris/c/seek1.c new file mode 100644 index 0000000..b22c8f9 --- /dev/null +++ b/sim/testsuite/cris/c/seek1.c @@ -0,0 +1,47 @@ +/* Check that basic (ll|f)seek sim functionality works. Also uses basic + file open/write functionality. */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int +main (void) +{ + FILE *f; + const char fname[] = "sk1test.dat"; + const char tsttxt[] + = "A random line of text, used to test correct read, write and seek.\n"; + char buf[sizeof tsttxt] = ""; + + f = fopen (fname, "w"); + if (f == NULL + || fwrite (tsttxt, 1, strlen (tsttxt), f) != strlen (tsttxt) + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + /* Using "rb" to make this test similar to the use in genconf.c in + GhostScript. */ + f = fopen (fname, "rb"); + if (f == NULL + || fseek (f, 0L, SEEK_END) != 0 + || ftell (f) != strlen (tsttxt)) + { + printf ("fail\n"); + exit (1); + } + + rewind (f); + if (fread (buf, 1, strlen (tsttxt), f) != strlen (tsttxt) + || strcmp (buf, tsttxt) != 0 + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/seek2.c b/sim/testsuite/cris/c/seek2.c new file mode 100644 index 0000000..9c24dfb --- /dev/null +++ b/sim/testsuite/cris/c/seek2.c @@ -0,0 +1,4 @@ +/* Simulator options: +#sim: --sysroot=@exedir@/ +*/ +#include "seek1.c" diff --git a/sim/testsuite/cris/c/seek3.c b/sim/testsuite/cris/c/seek3.c new file mode 100644 index 0000000..5e7b578 --- /dev/null +++ b/sim/testsuite/cris/c/seek3.c @@ -0,0 +1,49 @@ +/* Check for a sim bug, whereby the position was always unsigned + (truncation instead of sign-extension for 64-bit hosts). */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +int +main (void) +{ + FILE *f; + const char fname[] = "sk1test.dat"; + const char tsttxt[] + = "A random line of text, used to test correct read, write and seek.\n"; + char buf[sizeof tsttxt] = ""; + const char correct[] = "correct"; + char buf2[sizeof correct] = {0}; + int fd; + + f = fopen (fname, "wb"); + if (f == NULL + || fwrite (tsttxt, 1, strlen (tsttxt), f) != strlen (tsttxt) + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + /* We have to use file-descriptor calls instead of stream calls to + provoke the bug (for stream calls, the lseek call is canonicalized + to use SEEK_SET). */ + fd = open (fname, O_RDONLY); + if (fd < 0 + || read (fd, buf, strlen (tsttxt)) != strlen (tsttxt) + || strcmp (buf, tsttxt) != 0 + || lseek (fd, -30L, SEEK_CUR) != 36 + || read (fd, buf2, strlen (correct)) != strlen (correct) + || strcmp (buf2, correct) != 0) + { + printf ("fail\n"); + exit (1); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/seek4.c b/sim/testsuite/cris/c/seek4.c new file mode 100644 index 0000000..16f3bb0 --- /dev/null +++ b/sim/testsuite/cris/c/seek4.c @@ -0,0 +1,44 @@ +/* Check for a sim bug, whereby an invalid seek (to a negative offset) + did not return an error. */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +int +main (void) +{ + FILE *f; + const char fname[] = "sk1test.dat"; + const char tsttxt[] + = "A random line of text, used to test correct read, write and seek.\n"; + char buf[sizeof tsttxt] = ""; + int fd; + + f = fopen (fname, "wb"); + if (f == NULL + || fwrite (tsttxt, 1, strlen (tsttxt), f) != strlen (tsttxt) + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + fd = open (fname, O_RDONLY); + if (fd < 0 + || lseek (fd, -1L, SEEK_CUR) != -1 + || errno != EINVAL + || read (fd, buf, strlen (tsttxt)) != strlen (tsttxt) + || strcmp (buf, tsttxt) != 0) + { + printf ("fail\n"); + exit (1); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/setrlimit1.c b/sim/testsuite/cris/c/setrlimit1.c new file mode 100644 index 0000000..747f16c --- /dev/null +++ b/sim/testsuite/cris/c/setrlimit1.c @@ -0,0 +1,22 @@ +/* Check corner error case: specifying unimplemented resource. +#notarget: cris*-*-elf +*/ +#include <sys/time.h> +#include <sys/resource.h> +#include <unistd.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +int main (void) +{ + struct rlimit lim; + memset (&lim, 0, sizeof lim); + + if (setrlimit (RLIMIT_NPROC, &lim) != -1 + || errno != EINVAL) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/settls1.c b/sim/testsuite/cris/c/settls1.c new file mode 100644 index 0000000..bd55aa1 --- /dev/null +++ b/sim/testsuite/cris/c/settls1.c @@ -0,0 +1,49 @@ +/* Check that the syscall set_thread_area is supported and does the right thing. +#notarget: cris*-*-elf +*/ + +#include <unistd.h> +#include <sys/syscall.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> + +#ifndef SYS_set_thread_area +#define SYS_set_thread_area 243 +#endif + +int main (void) +{ + int ret; + + /* Check the error check that the low 8 bits must be 0. */ + ret = syscall (SYS_set_thread_area, 0xfeeb1ff0); + if (ret != -1 || errno != EINVAL) + { + perror ("tls1"); + abort (); + } + + ret = syscall (SYS_set_thread_area, 0xcafebe00); + if (ret != 0) + { + perror ("tls2"); + abort (); + } + + /* Check that we got the right result. */ +#ifdef __arch_v32 + asm ("move $pid,%0\n\tclear.b %0" : "=rm" (ret)); +#else + asm ("move $brp,%0" : "=rm" (ret)); +#endif + + if (ret != 0xcafebe00) + { + perror ("tls2"); + abort (); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sig1.c b/sim/testsuite/cris/c/sig1.c new file mode 100644 index 0000000..55499b7 --- /dev/null +++ b/sim/testsuite/cris/c/sig1.c @@ -0,0 +1,20 @@ +#include <stdio.h> +#include <signal.h> +#include <stdlib.h> + +void +leave (int n) +{ + exit (0); +} + +int +main (void) +{ + /* Check that the sigaction syscall (for signal) is interpreted, though + possibly ignored. */ + signal (SIGFPE, leave); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sig10.c b/sim/testsuite/cris/c/sig10.c new file mode 100644 index 0000000..ef54832 --- /dev/null +++ b/sim/testsuite/cris/c/sig10.c @@ -0,0 +1,33 @@ +/* Check that TRT happens when trying to IGN an non-ignorable signal, more than one thread. +#notarget: cris*-*-elf +#cc: additional_flags=-pthread +#xerror: +#output: Exiting pid 42 due to signal 9\n +#output: program stopped with signal 4 (*).\n +*/ + +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> +#include <sys/types.h> +#include <signal.h> + +static void * +process (void *arg) +{ + while (1) + sched_yield (); + return NULL; +} + +int main (void) +{ + pthread_t th_a; + signal (SIGKILL, SIG_IGN); + if (pthread_create (&th_a, NULL, process, (void *) "a") == 0) + kill (getpid (), SIGKILL); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sig11.c b/sim/testsuite/cris/c/sig11.c new file mode 100644 index 0000000..9c8aad7 --- /dev/null +++ b/sim/testsuite/cris/c/sig11.c @@ -0,0 +1,32 @@ +/* Check that TRT happens when getting a non-standard (realtime) signal, more than one thread. +#notarget: cris*-*-elf +#cc: additional_flags=-pthread +#xerror: +#output: Unimplemented signal: 77\n +#output: program stopped with signal 4 (*).\n +*/ + +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> +#include <sys/types.h> +#include <signal.h> + +static void * +process (void *arg) +{ + while (1) + sched_yield (); + return NULL; +} + +int main (void) +{ + pthread_t th_a; + if (pthread_create (&th_a, NULL, process, (void *) "a") == 0) + kill (getpid (), 77); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sig12.c b/sim/testsuite/cris/c/sig12.c new file mode 100644 index 0000000..5a2e65f --- /dev/null +++ b/sim/testsuite/cris/c/sig12.c @@ -0,0 +1,38 @@ +/* Check that TRT happens for a signal sent to a non-existent process/thread, more than one thread. +#cc: additional_flags=-pthread +#notarget: cris*-*-elf +*/ + +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> +#include <sys/types.h> +#include <signal.h> +#include <errno.h> + +static void * +process (void *arg) +{ + int i; + for (i = 0; i < 100; i++) + sched_yield (); + return NULL; +} + +int main (void) +{ + pthread_t th_a; + int retcode; + void *retval; + + if (pthread_create (&th_a, NULL, process, (void *) "a") != 0) + abort (); + if (kill (getpid () - 1, SIGBUS) != -1 + || errno != ESRCH + || pthread_join (th_a, &retval) != 0) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sig13.c b/sim/testsuite/cris/c/sig13.c new file mode 100644 index 0000000..4d71752 --- /dev/null +++ b/sim/testsuite/cris/c/sig13.c @@ -0,0 +1,8 @@ +/* As the included file, but specifying silent ENOSYS. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=enosys-quiet +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "sig7.c" diff --git a/sim/testsuite/cris/c/sig2.c b/sim/testsuite/cris/c/sig2.c new file mode 100644 index 0000000..65596ef --- /dev/null +++ b/sim/testsuite/cris/c/sig2.c @@ -0,0 +1,32 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <stdio.h> +#include <signal.h> +#include <stdlib.h> + +/* Like sig1.c, but using sigaction. */ + +void +leave (int n, siginfo_t *info, void *x) +{ + abort (); +} + +int +main (void) +{ + struct sigaction sa; + sa.sa_sigaction = leave; + sa.sa_flags = SA_RESTART | SA_SIGINFO; + sigemptyset (&sa.sa_mask); + + /* Check that the sigaction syscall (for signal) is interpreted, though + possibly ignored. */ + if (sigaction (SIGFPE, &sa, NULL) != 0) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sig3.c b/sim/testsuite/cris/c/sig3.c new file mode 100644 index 0000000..91de227 --- /dev/null +++ b/sim/testsuite/cris/c/sig3.c @@ -0,0 +1,13 @@ +/* Check that TRT happens at an abort (3) call, single thread. +#xerror: +#output: program stopped with signal 6 (*).\n +*/ + +#include <stdlib.h> +#include <stdio.h> +int main (void) +{ + abort (); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sig4.c b/sim/testsuite/cris/c/sig4.c new file mode 100644 index 0000000..57491f8 --- /dev/null +++ b/sim/testsuite/cris/c/sig4.c @@ -0,0 +1,30 @@ +/* Check that TRT happens at an abort (3) call, more than one thread. +#notarget: cris*-*-elf +#cc: additional_flags=-pthread +#xerror: +#output: Exiting pid 42 due to signal 6\n +#output: program stopped with signal 6 (*).\n +*/ + +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> + +static void * +process (void *arg) +{ + while (1) + sched_yield (); + return NULL; +} + +int main (void) +{ + pthread_t th_a; + if (pthread_create (&th_a, NULL, process, (void *) "a") == 0) + abort (); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sig5.c b/sim/testsuite/cris/c/sig5.c new file mode 100644 index 0000000..f80da2b --- /dev/null +++ b/sim/testsuite/cris/c/sig5.c @@ -0,0 +1,18 @@ +/* Check that TRT happens for an uncaught non-abort signal, single thread. +#xerror: +#output: Unimplemented signal: 7\n +#output: program stopped with signal 4 (*).\n +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <signal.h> +#include <unistd.h> + +int main (void) +{ + kill (getpid (), SIGBUS); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sig6.c b/sim/testsuite/cris/c/sig6.c new file mode 100644 index 0000000..a1f5720 --- /dev/null +++ b/sim/testsuite/cris/c/sig6.c @@ -0,0 +1,32 @@ +/* Check that TRT happens at an non-abort non-caught signal, more than one thread. +#notarget: cris*-*-elf +#cc: additional_flags=-pthread +#xerror: +#output: Exiting pid 42 due to signal 7\n +#output: program stopped with signal 4 (*).\n +*/ + +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> +#include <sys/types.h> +#include <signal.h> + +static void * +process (void *arg) +{ + while (1) + sched_yield (); + return NULL; +} + +int main (void) +{ + pthread_t th_a; + if (pthread_create (&th_a, NULL, process, (void *) "a") == 0) + kill (getpid (), SIGBUS); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sig7.c b/sim/testsuite/cris/c/sig7.c new file mode 100644 index 0000000..b04f7c8 --- /dev/null +++ b/sim/testsuite/cris/c/sig7.c @@ -0,0 +1,27 @@ +/* Check unsupported case of sigaction syscall. +#notarget: cris*-*-elf +#xerror: +#output: Unimplemented rt_sigaction syscall (0x8, 0x3df*\n +#output: program stopped with signal 4 (*).\n +*/ +#include <stdio.h> +#include <signal.h> +#include <stdlib.h> +#include <errno.h> + +int +main (void) +{ + struct sigaction sa; + int err; + sa.sa_sigaction = NULL; + sa.sa_flags = SA_RESTART | SA_SIGINFO; + sigemptyset (&sa.sa_mask); + + err = sigaction (SIGFPE, &sa, NULL); + if (err == -1 && errno == ENOSYS) + printf ("ENOSYS\n"); + + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sig8.c b/sim/testsuite/cris/c/sig8.c new file mode 100644 index 0000000..ea2d7f5 --- /dev/null +++ b/sim/testsuite/cris/c/sig8.c @@ -0,0 +1,21 @@ +/* Check that TRT happens for an ignored catchable signal, single thread. +#xerror: +#output: Unimplemented signal: 14\n +#output: program stopped with signal 4 (*).\n + + Sure, it'd probably be better to support signals in single-thread too, + but that's on an as-need basis, and I don't have a need for it yet. */ + +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <signal.h> +#include <unistd.h> + +int main (void) +{ + signal (SIGALRM, SIG_IGN); + kill (getpid (), SIGALRM); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sig9.c b/sim/testsuite/cris/c/sig9.c new file mode 100644 index 0000000..c86681b --- /dev/null +++ b/sim/testsuite/cris/c/sig9.c @@ -0,0 +1,36 @@ +/* Check that TRT happens at an non-abort ignored signal, more than one thread. +#notarget: cris*-*-elf +#cc: additional_flags=-pthread +*/ + +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> +#include <sys/types.h> +#include <signal.h> + +static void * +process (void *arg) +{ + int i; + for (i = 0; i < 100; i++) + sched_yield (); + return NULL; +} + +int main (void) +{ + pthread_t th_a; + int retcode; + void *retval; + signal (SIGALRM, SIG_IGN); + if (pthread_create (&th_a, NULL, process, (void *) "a") == 0) + kill (getpid (), SIGALRM); + retcode = pthread_join (th_a, &retval); + if (retcode != 0 || retval != NULL) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sigreturn1.c b/sim/testsuite/cris/c/sigreturn1.c new file mode 100644 index 0000000..40fc852 --- /dev/null +++ b/sim/testsuite/cris/c/sigreturn1.c @@ -0,0 +1,21 @@ +/* Test that TRT happens for spurious sigreturn calls. Single-thread. +#notarget: cris*-*-elf +#xerror: +#output: Invalid sigreturn syscall: no signal handler active (0x1, 0x2, 0x3, 0x4, 0x5, 0x6)\n +#output: program stopped with signal 4 (*).\n +*/ + +#include <unistd.h> +#include <sys/syscall.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> + +int main (void) +{ + int err = syscall (SYS_sigreturn, 1, 2, 3, 4, 5, 6); + if (err == -1 && errno == ENOSYS) + printf ("ENOSYS\n"); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sigreturn2.c b/sim/testsuite/cris/c/sigreturn2.c new file mode 100644 index 0000000..3848b5f --- /dev/null +++ b/sim/testsuite/cris/c/sigreturn2.c @@ -0,0 +1,38 @@ +/* Check that TRT happens for spurious sigreturn calls. Multiple threads. +#notarget: cris*-*-elf +#cc: additional_flags=-pthread +#xerror: +#output: Invalid sigreturn syscall: no signal handler active (0x1, 0x2, 0x3, 0x4, 0x5, 0x6)\n +#output: program stopped with signal 4 (*).\n +*/ + +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> +#include <sys/types.h> +#include <sys/syscall.h> +#include <signal.h> +#include <errno.h> + +static void * +process (void *arg) +{ + while (1) + sched_yield (); + return NULL; +} + +int main (void) +{ + pthread_t th_a; + if (pthread_create (&th_a, NULL, process, (void *) "a") == 0) + { + int err = syscall (SYS_sigreturn, 1, 2, 3, 4, 5, 6); + if (err == -1 && errno == ENOSYS) + printf ("ENOSYS\n"); + } + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sigreturn3.c b/sim/testsuite/cris/c/sigreturn3.c new file mode 100644 index 0000000..f5ed90f --- /dev/null +++ b/sim/testsuite/cris/c/sigreturn3.c @@ -0,0 +1,8 @@ +/* As the included file, but specifying silent ENOSYS. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=enosys-quiet +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "sigreturn1.c" diff --git a/sim/testsuite/cris/c/sigreturn4.c b/sim/testsuite/cris/c/sigreturn4.c new file mode 100644 index 0000000..456e312 --- /dev/null +++ b/sim/testsuite/cris/c/sigreturn4.c @@ -0,0 +1,9 @@ +/* As the included file, but specifying silent ENOSYS. +#notarget: cris*-*-elf +#cc: additional_flags=-pthread +#sim: --cris-unknown-syscall=enosys-quiet +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "sigreturn2.c" diff --git a/sim/testsuite/cris/c/sjlj.c b/sim/testsuite/cris/c/sjlj.c new file mode 100644 index 0000000..141faf6 --- /dev/null +++ b/sim/testsuite/cris/c/sjlj.c @@ -0,0 +1,34 @@ +/* Check that setjmp and longjmp stand a chance to work; that the used machine + primitives work in the simulator. */ + +#include <stdio.h> +#include <setjmp.h> +#include <stdlib.h> + +extern void f (void); + +int ok = 0; +jmp_buf b; + +int +main () +{ + int ret = setjmp (b); + + if (ret == 42) + ok = 100; + else if (ret == 0) + f (); + + if (ok == 100) + printf ("pass\n"); + else + printf ("fail\n"); + exit (0); +} + +void +f (void) +{ + longjmp (b, 42); +} diff --git a/sim/testsuite/cris/c/sock1.c b/sim/testsuite/cris/c/sock1.c new file mode 100644 index 0000000..e59f673 --- /dev/null +++ b/sim/testsuite/cris/c/sock1.c @@ -0,0 +1,32 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> + +/* Check that socketcall is suitably stubbed. */ + +int main (void) +{ + int ret = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (ret != -1) + { + fprintf (stderr, "sock: %d\n", ret); + abort (); + } + + if (errno != ENOSYS) + { + perror ("unexpected"); + abort (); + } + + printf ("pass\n"); + return 0; +} diff --git a/sim/testsuite/cris/c/stat1.c b/sim/testsuite/cris/c/stat1.c new file mode 100644 index 0000000..b5d14a3 --- /dev/null +++ b/sim/testsuite/cris/c/stat1.c @@ -0,0 +1,16 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +int main (void) +{ + struct stat buf; + + if (stat (".", &buf) != 0 + || !S_ISDIR (buf.st_mode)) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/stat2.c b/sim/testsuite/cris/c/stat2.c new file mode 100644 index 0000000..78c5c44 --- /dev/null +++ b/sim/testsuite/cris/c/stat2.c @@ -0,0 +1,20 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +int main (void) +{ + struct stat buf; + + if (lstat (".", &buf) != 0 + || !S_ISDIR (buf.st_mode)) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/stat3.c b/sim/testsuite/cris/c/stat3.c new file mode 100644 index 0000000..a248ec0 --- /dev/null +++ b/sim/testsuite/cris/c/stat3.c @@ -0,0 +1,26 @@ +/* Simulator options: +#sim: --sysroot=@exedir@ +*/ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) +{ + char path[1024] = "/"; + struct stat buf; + + strcat (path, argv[0]); + if (stat (".", &buf) != 0 + || !S_ISDIR (buf.st_mode)) + abort (); + if (stat (path, &buf) != 0 + || !S_ISREG (buf.st_mode)) + abort (); + printf ("pass\n"); + exit (0); +} + diff --git a/sim/testsuite/cris/c/stat4.c b/sim/testsuite/cris/c/stat4.c new file mode 100644 index 0000000..62415a3 --- /dev/null +++ b/sim/testsuite/cris/c/stat4.c @@ -0,0 +1,28 @@ +/* Simulator options: +#notarget: cris*-*-elf +#sim: --sysroot=@exedir@ +*/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) +{ + char path[1024] = "/"; + struct stat buf; + + strcat (path, argv[0]); + if (lstat (".", &buf) != 0 + || !S_ISDIR (buf.st_mode)) + abort (); + if (lstat (path, &buf) != 0 + || !S_ISREG (buf.st_mode)) + abort (); + printf ("pass\n"); + exit (0); +} + diff --git a/sim/testsuite/cris/c/stat5.c b/sim/testsuite/cris/c/stat5.c new file mode 100644 index 0000000..41ab493 --- /dev/null +++ b/sim/testsuite/cris/c/stat5.c @@ -0,0 +1,20 @@ +/* Check that lstat:ing an nonexistent file works as expected. +#notarget: cris*-*-elf +*/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +int main (void) +{ + struct stat buf; + + if (lstat ("nonexistent", &buf) == 0 || errno != ENOENT) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/stat7.c b/sim/testsuite/cris/c/stat7.c new file mode 100644 index 0000000..cbd5282 --- /dev/null +++ b/sim/testsuite/cris/c/stat7.c @@ -0,0 +1,26 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> + +int main (void) +{ + struct stat buf; + + /* From Linux, we get EFAULT. The simulator sends us EINVAL. */ + if (lstat (NULL, &buf) != -1 + || (errno != EINVAL && errno != EFAULT)) + { + perror ("lstat 1"); + abort (); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/stat8.c b/sim/testsuite/cris/c/stat8.c new file mode 100644 index 0000000..c7eb49f --- /dev/null +++ b/sim/testsuite/cris/c/stat8.c @@ -0,0 +1,26 @@ +/* For this test, we need to do the lstat syscall directly, or else + glibc gets a SEGV. +#notarget: cris*-*-elf +*/ + +#include <unistd.h> +#include <sys/syscall.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> + +int main (void) +{ + int ret; + + /* From Linux, we get EFAULT. The simulator sends us EINVAL. */ + ret = syscall (SYS_lstat64, ".", NULL); + if (ret != -1 || (errno != EINVAL && errno != EFAULT)) + { + perror ("lstat"); + abort (); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/syscall1.c b/sim/testsuite/cris/c/syscall1.c new file mode 100644 index 0000000..84aacb6 --- /dev/null +++ b/sim/testsuite/cris/c/syscall1.c @@ -0,0 +1,22 @@ +/* Test unknown-syscall output. +#notarget: cris*-*-elf +#xerror: +#output: Unimplemented syscall: 166 (0x1, 0x2, 0x3, 0x4, 0x5, 0x6)\n +#output: program stopped with signal 4 (*).\n +*/ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> + +int main (void) +{ + /* The number 166 is chosen because there's a gap for that number in + the CRIS asm/unistd.h. */ + int err = syscall (166, 1, 2, 3, 4, 5, 6); + if (err == -1 && errno == ENOSYS) + printf ("ENOSYS\n"); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/syscall2.c b/sim/testsuite/cris/c/syscall2.c new file mode 100644 index 0000000..b4dbead --- /dev/null +++ b/sim/testsuite/cris/c/syscall2.c @@ -0,0 +1,23 @@ +/* Test unknown-syscall output. +#notarget: cris*-*-elf +#xerror: +#output: Unimplemented syscall: 0 (0x3, 0x2, 0x1, 0x4, 0x6, 0x5)\n +#output: program stopped with signal 4 (*).\n +*/ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> + +int main (void) +{ + int err; + + /* Check special case of number 0 syscall. */ + err = syscall (0, 3, 2, 1, 4, 6, 5); + if (err == -1 && errno == ENOSYS) + printf ("ENOSYS\n"); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/syscall3.c b/sim/testsuite/cris/c/syscall3.c new file mode 100644 index 0000000..f4d02eb --- /dev/null +++ b/sim/testsuite/cris/c/syscall3.c @@ -0,0 +1,9 @@ +/* As the included file, just actually specifying the default. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=stop +#xerror: +#output: Unimplemented syscall: 166 (0x1, 0x2, 0x3, 0x4, 0x5, 0x6)\n +#output: program stopped with signal 4 (*).\n +*/ + +#include "syscall1.c" diff --git a/sim/testsuite/cris/c/syscall4.c b/sim/testsuite/cris/c/syscall4.c new file mode 100644 index 0000000..ba01cfd --- /dev/null +++ b/sim/testsuite/cris/c/syscall4.c @@ -0,0 +1,9 @@ +/* As the included file, just actually specifying the default. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=stop +#xerror: +#output: Unimplemented syscall: 0 (0x3, 0x2, 0x1, 0x4, 0x6, 0x5)\n +#output: program stopped with signal 4 (*).\n +*/ + +#include "syscall2.c" diff --git a/sim/testsuite/cris/c/syscall5.c b/sim/testsuite/cris/c/syscall5.c new file mode 100644 index 0000000..2eac900 --- /dev/null +++ b/sim/testsuite/cris/c/syscall5.c @@ -0,0 +1,9 @@ +/* As the included file, but specifying ENOSYS with message. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=enosys +#output: Unimplemented syscall: 166 (0x1, 0x2, 0x3, 0x4, 0x5, 0x6)\n +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "syscall1.c" diff --git a/sim/testsuite/cris/c/syscall6.c b/sim/testsuite/cris/c/syscall6.c new file mode 100644 index 0000000..91375df --- /dev/null +++ b/sim/testsuite/cris/c/syscall6.c @@ -0,0 +1,9 @@ +/* As the included file, but specifying ENOSYS with message. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=enosys +#output: Unimplemented syscall: 0 (0x3, 0x2, 0x1, 0x4, 0x6, 0x5)\n +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "syscall2.c" diff --git a/sim/testsuite/cris/c/syscall7.c b/sim/testsuite/cris/c/syscall7.c new file mode 100644 index 0000000..0f1daf1 --- /dev/null +++ b/sim/testsuite/cris/c/syscall7.c @@ -0,0 +1,8 @@ +/* As the included file, but specifying silent ENOSYS. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=enosys-quiet +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "syscall1.c" diff --git a/sim/testsuite/cris/c/syscall8.c b/sim/testsuite/cris/c/syscall8.c new file mode 100644 index 0000000..c579436 --- /dev/null +++ b/sim/testsuite/cris/c/syscall8.c @@ -0,0 +1,8 @@ +/* As the included file, but specifying silent ENOSYS. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=enosys-quiet +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "syscall2.c" diff --git a/sim/testsuite/cris/c/sysctl1.c b/sim/testsuite/cris/c/sysctl1.c new file mode 100644 index 0000000..6646fac --- /dev/null +++ b/sim/testsuite/cris/c/sysctl1.c @@ -0,0 +1,38 @@ +/* +#notarget: cris*-*-elf +*/ + +#include <unistd.h> +#include <sys/syscall.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> + +/* I can't seem to include the right things, so we do it brute force. */ +int main (void) +{ + static int sysctl_args[] = { 1, 4 }; + size_t x = 8; + + struct __sysctl_args { + int *name; + int nlen; + void *oldval; + size_t *oldlenp; + void *newval; + size_t newlen; + unsigned long __unused[4]; + } scargs + = + { + sysctl_args, + sizeof (sysctl_args) / sizeof (sysctl_args[0]), + (void *) -1, &x, NULL, 0 + }; + + if (syscall (SYS__sysctl, &scargs) != -1 + || errno != EFAULT) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sysctl2.c b/sim/testsuite/cris/c/sysctl2.c new file mode 100644 index 0000000..f27c37c --- /dev/null +++ b/sim/testsuite/cris/c/sysctl2.c @@ -0,0 +1,41 @@ +/* Check error message for invalid sysctl call. +#xerror: +#output: Unimplemented _sysctl syscall *\n +#output: program stopped with signal 4 (*).\n +#notarget: cris*-*-elf +*/ + +#include <unistd.h> +#include <sys/syscall.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> + +int main (void) +{ + static int sysctl_args[] = { 99, 99 }; + size_t x = 8; + + struct __sysctl_args { + int *name; + int nlen; + void *oldval; + size_t *oldlenp; + void *newval; + size_t newlen; + unsigned long __unused[4]; + } scargs + = + { + sysctl_args, + sizeof (sysctl_args) / sizeof (sysctl_args[0]), + (void *) -1, &x, NULL, 0 + }; + + int err = syscall (SYS__sysctl, &scargs); + if (err == -1 && errno == ENOSYS) + printf ("ENOSYS\n"); + printf ("xyzzy\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/sysctl3.c b/sim/testsuite/cris/c/sysctl3.c new file mode 100644 index 0000000..747e784 --- /dev/null +++ b/sim/testsuite/cris/c/sysctl3.c @@ -0,0 +1,8 @@ +/* As the included file, but specifying silent ENOSYS. +#notarget: cris*-*-elf +#sim: --cris-unknown-syscall=enosys-quiet +#output: ENOSYS\n +#output: xyzzy\n +*/ + +#include "sysctl2.c" diff --git a/sim/testsuite/cris/c/thread2.c b/sim/testsuite/cris/c/thread2.c new file mode 100644 index 0000000..c9ad2f9 --- /dev/null +++ b/sim/testsuite/cris/c/thread2.c @@ -0,0 +1,28 @@ +/* Compiler options: +#cc: additional_flags=-pthread +#notarget: cris*-*-elf + + A sanity check for syscalls resulting from + pthread_getschedparam and pthread_setschedparam. */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +int main (void) +{ + struct sched_param param; + int policy; + + if (pthread_getschedparam (pthread_self (), &policy, ¶m) != 0 + || policy != SCHED_OTHER + || param.sched_priority != 0) + abort (); + + if (pthread_setschedparam (pthread_self (), SCHED_OTHER, ¶m) != 0 + || param.sched_priority != 0) + abort (); + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/thread3.c b/sim/testsuite/cris/c/thread3.c new file mode 100644 index 0000000..3b6945a --- /dev/null +++ b/sim/testsuite/cris/c/thread3.c @@ -0,0 +1,46 @@ +/* Compiler options: +#cc: additional_flags=-pthread +#notarget: cris*-*-elf + + To test sched_yield in the presencs of threads. Core from ex1.c. */ + +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> +#include <stdlib.h> + +static void * +process (void *arg) +{ + int i; + for (i = 0; i < 10; i++) + { + if (sched_yield () != 0) + abort (); + } + return NULL; +} + +int +main (void) +{ + int retcode; + pthread_t th_a, th_b; + void *retval; + + retcode = pthread_create (&th_a, NULL, process, (void *) "a"); + if (retcode != 0) + abort (); + retcode = pthread_create (&th_b, NULL, process, (void *) "b"); + if (retcode != 0) + abort (); + retcode = pthread_join (th_a, &retval); + if (retcode != 0) + abort (); + retcode = pthread_join (th_b, &retval); + if (retcode != 0) + abort (); + printf ("pass\n"); + return 0; +} diff --git a/sim/testsuite/cris/c/thread4.c b/sim/testsuite/cris/c/thread4.c new file mode 100644 index 0000000..cfa2327 --- /dev/null +++ b/sim/testsuite/cris/c/thread4.c @@ -0,0 +1,50 @@ +/* Compiler options: +#notarget: cris*-*-elf +#cc: additional_flags=-pthread +#output: abb ok\n + + Testing a pthread corner case. Output will change with glibc + releases. */ + +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> +#include <stdlib.h> + +static void * +process (void *arg) +{ + int i; + + if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0) + abort (); + write (2, "a", 1); + for (i = 0; i < 10; i++) + { + sched_yield (); + pthread_testcancel (); + write (2, "b", 1); + } + return NULL; +} + +int +main (void) +{ + int retcode; + pthread_t th_a; + void *retval; + + retcode = pthread_create (&th_a, NULL, process, NULL); + sched_yield (); + sched_yield (); + sched_yield (); + sched_yield (); + retcode = pthread_cancel (th_a); + retcode = pthread_join (th_a, &retval); + if (retcode != 0) + abort (); + fprintf (stderr, " ok\n"); + return 0; +} diff --git a/sim/testsuite/cris/c/thread5.c b/sim/testsuite/cris/c/thread5.c new file mode 100644 index 0000000..494251f --- /dev/null +++ b/sim/testsuite/cris/c/thread5.c @@ -0,0 +1,77 @@ +/* Compiler options: +#notarget: cris*-*-elf +#cc: additional_flags=-pthread +#output: abbb ok\n + + Testing a signal handler corner case. */ + +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <signal.h> +#include <pthread.h> + +static void * +process (void *arg) +{ + write (2, "a", 1); + write (2, "b", 1); + write (2, "b", 1); + write (2, "b", 1); + return NULL; +} + +int ok = 0; +volatile int done = 0; + +void +sigusr1 (int signum) +{ + if (signum != SIGUSR1 || !ok) + abort (); + done = 1; +} + +int +main (void) +{ + int retcode; + pthread_t th_a; + void *retval; + sigset_t sigs; + + if (sigemptyset (&sigs) != 0) + abort (); + + retcode = pthread_create (&th_a, NULL, process, NULL); + if (retcode != 0) + abort (); + + if (signal (SIGUSR1, sigusr1) != SIG_DFL) + abort (); + if (pthread_sigmask (SIG_BLOCK, NULL, &sigs) != 0 + || sigaddset (&sigs, SIGUSR1) != 0 + || pthread_sigmask (SIG_BLOCK, &sigs, NULL) != 0) + abort (); + if (pthread_kill (pthread_self (), SIGUSR1) != 0 + || sched_yield () != 0 + || sched_yield () != 0 + || sched_yield () != 0) + abort (); + + ok = 1; + if (pthread_sigmask (SIG_UNBLOCK, NULL, &sigs) != 0 + || sigaddset (&sigs, SIGUSR1) != 0 + || pthread_sigmask (SIG_UNBLOCK, &sigs, NULL) != 0) + abort (); + + if (!done) + abort (); + + retcode = pthread_join (th_a, &retval); + if (retcode != 0) + abort (); + fprintf (stderr, " ok\n"); + return 0; +} diff --git a/sim/testsuite/cris/c/time1.c b/sim/testsuite/cris/c/time1.c new file mode 100644 index 0000000..3fcf0e1 --- /dev/null +++ b/sim/testsuite/cris/c/time1.c @@ -0,0 +1,46 @@ +/* Basic time functionality test: check that milliseconds are + incremented for each syscall (does not work on host). */ +#include <stdio.h> +#include <time.h> +#include <sys/time.h> +#include <string.h> +#include <stdlib.h> + +void err (const char *s) +{ + perror (s); + abort (); +} + +int +main (void) +{ + struct timeval t_m = {0, 0}; + struct timezone t_z = {0, 0}; + struct timeval t_m1 = {0, 0}; + int i; + + if (gettimeofday (&t_m, &t_z) != 0) + err ("gettimeofday"); + + for (i = 1; i < 10000; i++) + if (gettimeofday (&t_m1, NULL) != 0) + err ("gettimeofday 1"); + else + if (t_m1.tv_sec * 1000000 + t_m1.tv_usec + != (t_m.tv_sec * 1000000 + t_m.tv_usec + i * 1000)) + { + fprintf (stderr, "t0 (%ld, %ld), i %d, t1 (%ld, %ld)\n", + t_m.tv_sec, t_m.tv_usec, i, t_m1.tv_sec, t_m1.tv_usec); + abort (); + } + + if (time (NULL) != t_m1.tv_sec) + { + fprintf (stderr, "time != gettod\n"); + abort (); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/time2.c b/sim/testsuite/cris/c/time2.c new file mode 100644 index 0000000..20b69b4 --- /dev/null +++ b/sim/testsuite/cris/c/time2.c @@ -0,0 +1,18 @@ +/* CB_SYS_time doesn't implement the Linux time syscall; the return + value isn't written to the argument. */ + +#include <time.h> +#include <stdio.h> +#include <stdlib.h> + +int +main (void) +{ + time_t x = (time_t) -1; + time_t t = time (&x); + + if (t == (time_t) -1 || t != x) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/truncate1.c b/sim/testsuite/cris/c/truncate1.c new file mode 100644 index 0000000..477dc3d --- /dev/null +++ b/sim/testsuite/cris/c/truncate1.c @@ -0,0 +1,49 @@ +/* Check that the truncate syscall works trivially. +#notarget: cris*-*-elf +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifndef PREFIX +#define PREFIX +#endif +int +main (void) +{ + FILE *f; + const char fname[] = PREFIX "sk1test.dat"; + const char tsttxt1[] + = "This is the first and only line of this file.\n"; + const char tsttxt2[] = "Now there is a second line.\n"; + char buf[sizeof (tsttxt1) + sizeof (tsttxt2) - 1] = ""; + + f = fopen (fname, "w+"); + if (f == NULL + || fwrite (tsttxt1, 1, strlen (tsttxt1), f) != strlen (tsttxt1) + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + if (truncate (fname, strlen(tsttxt1) - 10) != 0) + { + perror ("truncate"); + exit (1); + } + + f = fopen (fname, "r"); + if (f == NULL + || fread (buf, 1, sizeof (buf), f) != strlen (tsttxt1) - 10 + || strncmp (buf, tsttxt1, strlen (tsttxt1) - 10) != 0 + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/truncate2.c b/sim/testsuite/cris/c/truncate2.c new file mode 100644 index 0000000..a4c6470 --- /dev/null +++ b/sim/testsuite/cris/c/truncate2.c @@ -0,0 +1,6 @@ +/* +#sim: --sysroot=@exedir@ +#notarget: cris*-*-elf +*/ +#define PREFIX "/" +#include "truncate1.c" diff --git a/sim/testsuite/cris/c/ugetrlimit1.c b/sim/testsuite/cris/c/ugetrlimit1.c new file mode 100644 index 0000000..2a49b95 --- /dev/null +++ b/sim/testsuite/cris/c/ugetrlimit1.c @@ -0,0 +1,21 @@ +/* Check corner error case: specifying unimplemented resource. +#notarget: cris*-*-elf +*/ + +#include <sys/time.h> +#include <sys/resource.h> +#include <unistd.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> + +int main (void) +{ + struct rlimit lim; + + if (getrlimit (RLIMIT_NPROC, &lim) != -1 + || errno != EINVAL) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/uname1.c b/sim/testsuite/cris/c/uname1.c new file mode 100644 index 0000000..83518d6 --- /dev/null +++ b/sim/testsuite/cris/c/uname1.c @@ -0,0 +1,21 @@ +/* Check that the right machine name appears in the uname result. +#notarget: *-*-elf +*/ +#include <sys/utsname.h> +#include <stdio.h> +#include <stdlib.h> +int main (void) +{ + struct utsname buf; + if (uname (&buf) != 0 + || strcmp (buf.machine, +#ifdef __arch_v32 + "crisv32" +#else + "cris" +#endif + ) != 0) + abort (); + printf ("pass\n"); + exit (0); +} diff --git a/sim/testsuite/cris/c/writev1.c b/sim/testsuite/cris/c/writev1.c new file mode 100644 index 0000000..fad5b7f --- /dev/null +++ b/sim/testsuite/cris/c/writev1.c @@ -0,0 +1,25 @@ +/* Trivial test of writev. +#notarget: cris*-*-elf +#output: abcdefghijklmn\npass\n +*/ +#include <sys/uio.h> +#include <stdlib.h> +#include <stdio.h> + +#define X(x) {x, sizeof (x) -1} +struct iovec v[] = { + X("a"), + X("bcd"), + X("efghi"), + X("j"), + X("klmn\n"), +}; + +int main (void) +{ + if (writev (1, v, sizeof v / sizeof (v[0])) != 15) + abort (); + + printf ("pass\n"); + return 0; +} diff --git a/sim/testsuite/cris/c/writev2.c b/sim/testsuite/cris/c/writev2.c new file mode 100644 index 0000000..5cb92b6 --- /dev/null +++ b/sim/testsuite/cris/c/writev2.c @@ -0,0 +1,28 @@ +/* Trivial test of failing writev: invalid file descriptor. +#notarget: cris*-*-elf +*/ +#include <sys/uio.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +#define X(x) {x, sizeof (x) -1} +struct iovec v[] = { + X("a"), + X("bcd"), + X("efghi"), + X("j"), + X("klmn\n"), +}; + +int main (void) +{ + if (writev (99, v, sizeof v / sizeof (v[0])) != -1 + /* The simulator write gives EINVAL instead of EBADF; let's + cope. */ + || (errno != EBADF && errno != EINVAL)) + abort (); + + printf ("pass\n"); + return 0; +} |