summaryrefslogtreecommitdiff
path: root/sim/testsuite/sim/cris/c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/testsuite/sim/cris/c')
-rw-r--r--sim/testsuite/sim/cris/c/append1.c51
-rw-r--r--sim/testsuite/sim/cris/c/c.exp211
-rw-r--r--sim/testsuite/sim/cris/c/clone1.c90
-rw-r--r--sim/testsuite/sim/cris/c/clone2.c6
-rw-r--r--sim/testsuite/sim/cris/c/clone3.c45
-rw-r--r--sim/testsuite/sim/cris/c/clone4.c61
-rw-r--r--sim/testsuite/sim/cris/c/clone5.c32
-rw-r--r--sim/testsuite/sim/cris/c/ex1.c54
-rw-r--r--sim/testsuite/sim/cris/c/fcntl1.c16
-rw-r--r--sim/testsuite/sim/cris/c/fdopen1.c54
-rw-r--r--sim/testsuite/sim/cris/c/fdopen2.c52
-rw-r--r--sim/testsuite/sim/cris/c/freopen1.c52
-rw-r--r--sim/testsuite/sim/cris/c/ftruncate1.c52
-rw-r--r--sim/testsuite/sim/cris/c/ftruncate2.c39
-rw-r--r--sim/testsuite/sim/cris/c/getcwd1.c18
-rw-r--r--sim/testsuite/sim/cris/c/gettod.c27
-rw-r--r--sim/testsuite/sim/cris/c/hello.c7
-rw-r--r--sim/testsuite/sim/cris/c/kill1.c30
-rw-r--r--sim/testsuite/sim/cris/c/kill2.c16
-rw-r--r--sim/testsuite/sim/cris/c/kill3.c16
-rw-r--r--sim/testsuite/sim/cris/c/mapbrk.c39
-rw-r--r--sim/testsuite/sim/cris/c/mmap1.c48
-rw-r--r--sim/testsuite/sim/cris/c/mmap2.c48
-rw-r--r--sim/testsuite/sim/cris/c/mmap3.c33
-rw-r--r--sim/testsuite/sim/cris/c/mprotect1.c16
-rw-r--r--sim/testsuite/sim/cris/c/mremap.c31
-rw-r--r--sim/testsuite/sim/cris/c/openpf1.c38
-rw-r--r--sim/testsuite/sim/cris/c/openpf2.c16
-rw-r--r--sim/testsuite/sim/cris/c/openpf3.c49
-rw-r--r--sim/testsuite/sim/cris/c/openpf4.c5
-rw-r--r--sim/testsuite/sim/cris/c/openpf5.c56
-rw-r--r--sim/testsuite/sim/cris/c/pipe1.c47
-rw-r--r--sim/testsuite/sim/cris/c/pipe2.c124
-rw-r--r--sim/testsuite/sim/cris/c/pipe3.c48
-rw-r--r--sim/testsuite/sim/cris/c/pipe4.c66
-rw-r--r--sim/testsuite/sim/cris/c/pipe5.c59
-rw-r--r--sim/testsuite/sim/cris/c/pipe6.c111
-rw-r--r--sim/testsuite/sim/cris/c/pipe7.c21
-rw-r--r--sim/testsuite/sim/cris/c/readlink1.c20
-rw-r--r--sim/testsuite/sim/cris/c/readlink10.c18
-rw-r--r--sim/testsuite/sim/cris/c/readlink2.c73
-rw-r--r--sim/testsuite/sim/cris/c/readlink3.c6
-rw-r--r--sim/testsuite/sim/cris/c/readlink4.c62
-rw-r--r--sim/testsuite/sim/cris/c/readlink5.c8
-rw-r--r--sim/testsuite/sim/cris/c/readlink6.c5
-rw-r--r--sim/testsuite/sim/cris/c/readlink7.c6
-rw-r--r--sim/testsuite/sim/cris/c/readlink8.c8
-rw-r--r--sim/testsuite/sim/cris/c/readlink9.c23
-rw-r--r--sim/testsuite/sim/cris/c/rename2.c38
-rw-r--r--sim/testsuite/sim/cris/c/rtsigprocmask1.c45
-rw-r--r--sim/testsuite/sim/cris/c/rtsigsuspend1.c18
-rw-r--r--sim/testsuite/sim/cris/c/sched1.c15
-rw-r--r--sim/testsuite/sim/cris/c/sched2.c19
-rw-r--r--sim/testsuite/sim/cris/c/sched3.c24
-rw-r--r--sim/testsuite/sim/cris/c/sched4.c24
-rw-r--r--sim/testsuite/sim/cris/c/sched5.c19
-rw-r--r--sim/testsuite/sim/cris/c/sched6.c15
-rw-r--r--sim/testsuite/sim/cris/c/sched7.c17
-rw-r--r--sim/testsuite/sim/cris/c/sched8.c19
-rw-r--r--sim/testsuite/sim/cris/c/sched9.c24
-rw-r--r--sim/testsuite/sim/cris/c/seek1.c47
-rw-r--r--sim/testsuite/sim/cris/c/seek2.c4
-rw-r--r--sim/testsuite/sim/cris/c/setrlimit1.c22
-rw-r--r--sim/testsuite/sim/cris/c/sig1.c20
-rw-r--r--sim/testsuite/sim/cris/c/sig10.c33
-rw-r--r--sim/testsuite/sim/cris/c/sig11.c32
-rw-r--r--sim/testsuite/sim/cris/c/sig12.c38
-rw-r--r--sim/testsuite/sim/cris/c/sig2.c32
-rw-r--r--sim/testsuite/sim/cris/c/sig3.c13
-rw-r--r--sim/testsuite/sim/cris/c/sig4.c30
-rw-r--r--sim/testsuite/sim/cris/c/sig5.c16
-rw-r--r--sim/testsuite/sim/cris/c/sig6.c32
-rw-r--r--sim/testsuite/sim/cris/c/sig7.c24
-rw-r--r--sim/testsuite/sim/cris/c/sig8.c19
-rw-r--r--sim/testsuite/sim/cris/c/sig9.c36
-rw-r--r--sim/testsuite/sim/cris/c/sigreturn1.c18
-rw-r--r--sim/testsuite/sim/cris/c/sigreturn2.c33
-rw-r--r--sim/testsuite/sim/cris/c/sjlj.c34
-rw-r--r--sim/testsuite/sim/cris/c/sock1.c32
-rw-r--r--sim/testsuite/sim/cris/c/stat1.c16
-rw-r--r--sim/testsuite/sim/cris/c/stat2.c20
-rw-r--r--sim/testsuite/sim/cris/c/stat3.c26
-rw-r--r--sim/testsuite/sim/cris/c/stat4.c28
-rw-r--r--sim/testsuite/sim/cris/c/stat5.c20
-rw-r--r--sim/testsuite/sim/cris/c/stat7.c26
-rw-r--r--sim/testsuite/sim/cris/c/stat8.c26
-rw-r--r--sim/testsuite/sim/cris/c/syscall1.c19
-rw-r--r--sim/testsuite/sim/cris/c/syscall2.c18
-rw-r--r--sim/testsuite/sim/cris/c/sysctl1.c38
-rw-r--r--sim/testsuite/sim/cris/c/sysctl2.c38
-rw-r--r--sim/testsuite/sim/cris/c/thread2.c28
-rw-r--r--sim/testsuite/sim/cris/c/thread3.c46
-rw-r--r--sim/testsuite/sim/cris/c/thread4.c50
-rw-r--r--sim/testsuite/sim/cris/c/thread5.c77
-rw-r--r--sim/testsuite/sim/cris/c/time1.c46
-rw-r--r--sim/testsuite/sim/cris/c/truncate1.c49
-rw-r--r--sim/testsuite/sim/cris/c/truncate2.c6
-rw-r--r--sim/testsuite/sim/cris/c/ugetrlimit1.c21
98 files changed, 3403 insertions, 0 deletions
diff --git a/sim/testsuite/sim/cris/c/append1.c b/sim/testsuite/sim/cris/c/append1.c
new file mode 100644
index 00000000000..0acd59d2827
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/c.exp b/sim/testsuite/sim/cris/c/c.exp
new file mode 100644
index 00000000000..c76fc773112
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/c.exp
@@ -0,0 +1,211 @@
+# Copyright (C) 2005 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# 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"
+}
+
+# Using target_compile, since it is less noisy,
+if { [target_compile $srcdir/$subdir/hello.c compilercheck.x \
+ "executable" "" ] == "" } {
+ set has_cc 1
+} {
+ 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]] {
+ 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) ""
+
+ # 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"
+ }
+ }
+
+ 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
+ }
+
+ 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 status [lindex $result 0]
+ set output [lindex $result 1]
+
+ 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/sim/cris/c/clone1.c b/sim/testsuite/sim/cris/c/clone1.c
new file mode 100644
index 00000000000..163b18647a8
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/clone2.c b/sim/testsuite/sim/cris/c/clone2.c
new file mode 100644
index 00000000000..e433a778b34
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/clone3.c b/sim/testsuite/sim/cris/c/clone3.c
new file mode 100644
index 00000000000..0a97484adac
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/clone4.c b/sim/testsuite/sim/cris/c/clone4.c
new file mode 100644
index 00000000000..81489ddc419
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/clone5.c b/sim/testsuite/sim/cris/c/clone5.c
new file mode 100644
index 00000000000..b642a2f1a35
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/clone5.c
@@ -0,0 +1,32 @@
+/* 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>
+
+int pip[2];
+
+int
+process (void *arg)
+{
+ return 0;
+}
+
+int
+main (void)
+{
+ int retcode;
+ long stack[16384];
+
+ clone (process, (char *) stack + sizeof (stack) - 64, 0, "cba");
+ printf ("xyzzy\n");
+ return 0;
+}
diff --git a/sim/testsuite/sim/cris/c/ex1.c b/sim/testsuite/sim/cris/c/ex1.c
new file mode 100644
index 00000000000..2447319f71a
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/fcntl1.c b/sim/testsuite/sim/cris/c/fcntl1.c
new file mode 100644
index 00000000000..e180841645a
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/fcntl1.c
@@ -0,0 +1,16 @@
+/* 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>
+
+int main (void)
+{
+ fcntl (1, 42);
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/fdopen1.c b/sim/testsuite/sim/cris/c/fdopen1.c
new file mode 100644
index 00000000000..cdfe19af7d7
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/fdopen2.c b/sim/testsuite/sim/cris/c/fdopen2.c
new file mode 100644
index 00000000000..6a59f367a34
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/freopen1.c b/sim/testsuite/sim/cris/c/freopen1.c
new file mode 100644
index 00000000000..eeb6079fdb5
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/freopen1.c
@@ -0,0 +1,52 @@
+/* Check that basic freopen functionality works.
+#xfail: *-*-*
+ Currently doesn't work, because syscall.c:cb_syscall case
+ CB_SYS_write intercepts writes to fd 1 and 2. */
+
+#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/sim/cris/c/ftruncate1.c b/sim/testsuite/sim/cris/c/ftruncate1.c
new file mode 100644
index 00000000000..46b8756705c
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/ftruncate2.c b/sim/testsuite/sim/cris/c/ftruncate2.c
new file mode 100644
index 00000000000..f1ef18c6aa6
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/getcwd1.c b/sim/testsuite/sim/cris/c/getcwd1.c
new file mode 100644
index 00000000000..3838916143a
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/gettod.c b/sim/testsuite/sim/cris/c/gettod.c
new file mode 100644
index 00000000000..18a000cd45c
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/hello.c b/sim/testsuite/sim/cris/c/hello.c
new file mode 100644
index 00000000000..fb403ba9961
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/kill1.c b/sim/testsuite/sim/cris/c/kill1.c
new file mode 100644
index 00000000000..e5c53a0daf8
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/kill2.c b/sim/testsuite/sim/cris/c/kill2.c
new file mode 100644
index 00000000000..183091cf664
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/kill2.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)
+{
+ kill (getpid (), SIGABRT);
+ printf ("undead\n");
+ exit (1);
+}
diff --git a/sim/testsuite/sim/cris/c/kill3.c b/sim/testsuite/sim/cris/c/kill3.c
new file mode 100644
index 00000000000..b70f3d324dc
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/mapbrk.c b/sim/testsuite/sim/cris/c/mapbrk.c
new file mode 100644
index 00000000000..1aff7622bc2
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/mmap1.c b/sim/testsuite/sim/cris/c/mmap1.c
new file mode 100644
index 00000000000..b803f0c431e
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/mmap1.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_PRIVATE, fd, 0);
+
+ if (memmem (a, size, str, strlen (str) + 1) == NULL)
+ abort ();
+
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/mmap2.c b/sim/testsuite/sim/cris/c/mmap2.c
new file mode 100644
index 00000000000..35139a0ed9a
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/mmap3.c b/sim/testsuite/sim/cris/c/mmap3.c
new file mode 100644
index 00000000000..34401fa0c90
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/mprotect1.c b/sim/testsuite/sim/cris/c/mprotect1.c
new file mode 100644
index 00000000000..ef249ec691f
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/mprotect1.c
@@ -0,0 +1,16 @@
+/* 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>
+
+int main (int argc, char *argv[])
+{
+ mprotect (0, 8193, PROT_EXEC);
+ printf ("xyzzy\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/mremap.c b/sim/testsuite/sim/cris/c/mremap.c
new file mode 100644
index 00000000000..e78a8a43f7a
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/openpf1.c b/sim/testsuite/sim/cris/c/openpf1.c
new file mode 100644
index 00000000000..1d71e0bddb0
--- /dev/null
+++ b/sim/testsuite/sim/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 ();
+ close (f);
+
+ /* Cover another execution path. */
+ if (fopen ("/nonexistent", "rb") != NULL
+ || errno != ENOENT)
+ abort ();
+ printf ("pass\n");
+ return 0;
+}
diff --git a/sim/testsuite/sim/cris/c/openpf2.c b/sim/testsuite/sim/cris/c/openpf2.c
new file mode 100644
index 00000000000..fe7c265a272
--- /dev/null
+++ b/sim/testsuite/sim/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 ();
+ close (f);
+ printf ("pass\n");
+ return 0;
+}
diff --git a/sim/testsuite/sim/cris/c/openpf3.c b/sim/testsuite/sim/cris/c/openpf3.c
new file mode 100644
index 00000000000..557adee92de
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/openpf4.c b/sim/testsuite/sim/cris/c/openpf4.c
new file mode 100644
index 00000000000..d3fdcfe2f90
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/openpf5.c b/sim/testsuite/sim/cris/c/openpf5.c
new file mode 100644
index 00000000000..1f86ea283d4
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/pipe1.c b/sim/testsuite/sim/cris/c/pipe1.c
new file mode 100644
index 00000000000..ddc4285e02f
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/pipe1.c
@@ -0,0 +1,47 @@
+/* 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>
+
+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/sim/cris/c/pipe2.c b/sim/testsuite/sim/cris/c/pipe2.c
new file mode 100644
index 00000000000..ccb97f82d4e
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/pipe2.c
@@ -0,0 +1,124 @@
+/* Check that closing a pipe with a nonempty buffer works.
+#notarget: cris*-*-elf
+#output: got: a\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>
+
+int pip[2];
+
+int pipemax;
+
+int
+process (void *arg)
+{
+ char *s = arg;
+ char *buf = malloc (pipemax * 100);
+ 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 should only successful for at most the PIPE_MAX
+ part, but no error. */
+ ret = write (pip[1], buf, pipemax * 10);
+ if (ret != 0 && ret != pipemax - 1 && ret != pipemax)
+ {
+ fprintf (stderr, "ret: %d\n", ret);
+ 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]);
+
+ 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/sim/cris/c/pipe3.c b/sim/testsuite/sim/cris/c/pipe3.c
new file mode 100644
index 00000000000..bf08a38e1f0
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/pipe4.c b/sim/testsuite/sim/cris/c/pipe4.c
new file mode 100644
index 00000000000..1cb309f9dc8
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/pipe5.c b/sim/testsuite/sim/cris/c/pipe5.c
new file mode 100644
index 00000000000..abf1c9fcd99
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/pipe6.c b/sim/testsuite/sim/cris/c/pipe6.c
new file mode 100644
index 00000000000..a8830cc3e69
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/pipe7.c b/sim/testsuite/sim/cris/c/pipe7.c
new file mode 100644
index 00000000000..552ddb8e1e8
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/readlink1.c b/sim/testsuite/sim/cris/c/readlink1.c
new file mode 100644
index 00000000000..1898e8eceb5
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/readlink10.c b/sim/testsuite/sim/cris/c/readlink10.c
new file mode 100644
index 00000000000..21744083edd
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/readlink2.c b/sim/testsuite/sim/cris/c/readlink2.c
new file mode 100644
index 00000000000..5a0d8785caf
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/readlink2.c
@@ -0,0 +1,73 @@
+/*
+#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];
+
+ /* This is a special feature handled in the simulator. The "42"
+ should be formed from getpid () if this was a real program. */
+ if (readlink ("/proc/42/exe", buf, sizeof (buf)) < 0)
+ abort ();
+
+ /* 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/sim/cris/c/readlink3.c b/sim/testsuite/sim/cris/c/readlink3.c
new file mode 100644
index 00000000000..94cff727e38
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/readlink4.c b/sim/testsuite/sim/cris/c/readlink4.c
new file mode 100644
index 00000000000..07a01e66453
--- /dev/null
+++ b/sim/testsuite/sim/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 (rindex (buf, '/') == NULL)
+ strcat (buf, "./");
+
+ for (i = rindex (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/sim/cris/c/readlink5.c b/sim/testsuite/sim/cris/c/readlink5.c
new file mode 100644
index 00000000000..11de3487111
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/readlink6.c b/sim/testsuite/sim/cris/c/readlink6.c
new file mode 100644
index 00000000000..4bac20d8190
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/readlink7.c b/sim/testsuite/sim/cris/c/readlink7.c
new file mode 100644
index 00000000000..9c2b3b732c8
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/readlink8.c b/sim/testsuite/sim/cris/c/readlink8.c
new file mode 100644
index 00000000000..55f6fe8541f
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/readlink9.c b/sim/testsuite/sim/cris/c/readlink9.c
new file mode 100644
index 00000000000..27880543637
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/rename2.c b/sim/testsuite/sim/cris/c/rename2.c
new file mode 100644
index 00000000000..39387d1ff31
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/rtsigprocmask1.c b/sim/testsuite/sim/cris/c/rtsigprocmask1.c
new file mode 100644
index 00000000000..0eee76845ef
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/rtsigprocmask1.c
@@ -0,0 +1,45 @@
+/* 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>
+
+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. */
+ pthread_sigmask (SIG_BLOCK + SIG_UNBLOCK + SIG_SETMASK,
+ NULL, &sigs);
+ printf ("xyzzy\n");
+ return 0;
+}
diff --git a/sim/testsuite/sim/cris/c/rtsigsuspend1.c b/sim/testsuite/sim/cris/c/rtsigsuspend1.c
new file mode 100644
index 00000000000..4a5ee3fd9c4
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/rtsigsuspend1.c
@@ -0,0 +1,18 @@
+/* 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>
+
+int main (void)
+{
+ syscall (SYS_rt_sigsuspend, 1, 2);
+ printf ("xyzzy\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/sched1.c b/sim/testsuite/sim/cris/c/sched1.c
new file mode 100644
index 00000000000..04dae4bd5db
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/sched1.c
@@ -0,0 +1,15 @@
+/*
+#notarget: cris*-*-elf
+*/
+
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main (void)
+{
+ if (sched_getscheduler (getpid ()) != SCHED_OTHER)
+ abort ();
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/sched2.c b/sim/testsuite/sim/cris/c/sched2.c
new file mode 100644
index 00000000000..5371c787f77
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/sched2.c
@@ -0,0 +1,19 @@
+/*
+#notarget: cris*-*-elf
+*/
+
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.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/sim/cris/c/sched3.c b/sim/testsuite/sim/cris/c/sched3.c
new file mode 100644
index 00000000000..601e7e00eea
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/sched3.c
@@ -0,0 +1,24 @@
+/*
+#notarget: cris*-*-elf
+*/
+
+#include <sched.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.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/sim/cris/c/sched4.c b/sim/testsuite/sim/cris/c/sched4.c
new file mode 100644
index 00000000000..57f761fe535
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/sched4.c
@@ -0,0 +1,24 @@
+/*
+#notarget: cris*-*-elf
+*/
+
+#include <sched.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.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/sim/cris/c/sched5.c b/sim/testsuite/sim/cris/c/sched5.c
new file mode 100644
index 00000000000..ddfe14d03c3
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sched6.c b/sim/testsuite/sim/cris/c/sched6.c
new file mode 100644
index 00000000000..d5adedc1a35
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sched7.c b/sim/testsuite/sim/cris/c/sched7.c
new file mode 100644
index 00000000000..35d006bca6a
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sched8.c b/sim/testsuite/sim/cris/c/sched8.c
new file mode 100644
index 00000000000..cd3e06e6488
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sched9.c b/sim/testsuite/sim/cris/c/sched9.c
new file mode 100644
index 00000000000..8499e43fb8c
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/seek1.c b/sim/testsuite/sim/cris/c/seek1.c
new file mode 100644
index 00000000000..b22c8f9e9b1
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/seek2.c b/sim/testsuite/sim/cris/c/seek2.c
new file mode 100644
index 00000000000..9c24dfbdb08
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/seek2.c
@@ -0,0 +1,4 @@
+/* Simulator options:
+#sim: --sysroot=@exedir@/
+*/
+#include "seek1.c"
diff --git a/sim/testsuite/sim/cris/c/setrlimit1.c b/sim/testsuite/sim/cris/c/setrlimit1.c
new file mode 100644
index 00000000000..747f16caa7f
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sig1.c b/sim/testsuite/sim/cris/c/sig1.c
new file mode 100644
index 00000000000..55499b799eb
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sig10.c b/sim/testsuite/sim/cris/c/sig10.c
new file mode 100644
index 00000000000..d9263081c61
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sig11.c b/sim/testsuite/sim/cris/c/sig11.c
new file mode 100644
index 00000000000..1661f9b409d
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sig12.c b/sim/testsuite/sim/cris/c/sig12.c
new file mode 100644
index 00000000000..5a2e65fe9c3
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sig2.c b/sim/testsuite/sim/cris/c/sig2.c
new file mode 100644
index 00000000000..65596ef2eea
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sig3.c b/sim/testsuite/sim/cris/c/sig3.c
new file mode 100644
index 00000000000..f6137290929
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sig4.c b/sim/testsuite/sim/cris/c/sig4.c
new file mode 100644
index 00000000000..6d7ec0e5cb4
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sig5.c b/sim/testsuite/sim/cris/c/sig5.c
new file mode 100644
index 00000000000..674621e1722
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/sig5.c
@@ -0,0 +1,16 @@
+/* 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>
+int main (void)
+{
+ kill (getpid (), SIGBUS);
+ printf ("xyzzy\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/sig6.c b/sim/testsuite/sim/cris/c/sig6.c
new file mode 100644
index 00000000000..3862cf2ee49
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sig7.c b/sim/testsuite/sim/cris/c/sig7.c
new file mode 100644
index 00000000000..2e70a430431
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/sig7.c
@@ -0,0 +1,24 @@
+/* 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>
+
+int
+main (void)
+{
+ struct sigaction sa;
+ sa.sa_sigaction = NULL;
+ sa.sa_flags = SA_RESTART | SA_SIGINFO;
+ sigemptyset (&sa.sa_mask);
+
+ if (sigaction (SIGFPE, &sa, NULL) != 0)
+ abort ();
+
+ printf ("xyzzy\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/sig8.c b/sim/testsuite/sim/cris/c/sig8.c
new file mode 100644
index 00000000000..8a52b217666
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/sig8.c
@@ -0,0 +1,19 @@
+/* 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>
+int main (void)
+{
+ signal (SIGALRM, SIG_IGN);
+ kill (getpid (), SIGALRM);
+ printf ("xyzzy\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/sig9.c b/sim/testsuite/sim/cris/c/sig9.c
new file mode 100644
index 00000000000..c86681b4322
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sigreturn1.c b/sim/testsuite/sim/cris/c/sigreturn1.c
new file mode 100644
index 00000000000..ddb0d02d719
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/sigreturn1.c
@@ -0,0 +1,18 @@
+/* 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>
+
+int main (void)
+{
+ syscall (SYS_sigreturn, 1, 2, 3, 4, 5, 6);
+ printf ("xyzzy\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/sigreturn2.c b/sim/testsuite/sim/cris/c/sigreturn2.c
new file mode 100644
index 00000000000..f0157f0488d
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/sigreturn2.c
@@ -0,0 +1,33 @@
+/* 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>
+
+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)
+ syscall (SYS_sigreturn, 1, 2, 3, 4, 5, 6);
+ printf ("xyzzy\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/sjlj.c b/sim/testsuite/sim/cris/c/sjlj.c
new file mode 100644
index 00000000000..141faf6e612
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sock1.c b/sim/testsuite/sim/cris/c/sock1.c
new file mode 100644
index 00000000000..e59f6730523
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/stat1.c b/sim/testsuite/sim/cris/c/stat1.c
new file mode 100644
index 00000000000..b5d14a388e2
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/stat2.c b/sim/testsuite/sim/cris/c/stat2.c
new file mode 100644
index 00000000000..78c5c44f910
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/stat3.c b/sim/testsuite/sim/cris/c/stat3.c
new file mode 100644
index 00000000000..a248ec0864c
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/stat4.c b/sim/testsuite/sim/cris/c/stat4.c
new file mode 100644
index 00000000000..62415a340e8
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/stat5.c b/sim/testsuite/sim/cris/c/stat5.c
new file mode 100644
index 00000000000..41ab493fd5c
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/stat7.c b/sim/testsuite/sim/cris/c/stat7.c
new file mode 100644
index 00000000000..cbd5282b70a
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/stat8.c b/sim/testsuite/sim/cris/c/stat8.c
new file mode 100644
index 00000000000..c7eb49f5403
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/syscall1.c b/sim/testsuite/sim/cris/c/syscall1.c
new file mode 100644
index 00000000000..5b8cfda7b51
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/syscall1.c
@@ -0,0 +1,19 @@
+/* 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>
+
+int main (void)
+{
+ /* The number 166 is chosen because there's a gap for that number in
+ the CRIS asm/unistd.h. */
+ syscall (166, 1, 2, 3, 4, 5, 6);
+ printf ("xyzzy\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/syscall2.c b/sim/testsuite/sim/cris/c/syscall2.c
new file mode 100644
index 00000000000..4497588dd24
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/syscall2.c
@@ -0,0 +1,18 @@
+/* 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>
+
+int main (void)
+{
+ /* Check special case of number 0 syscall. */
+ syscall (0, 3, 2, 1, 4, 6, 5);
+ printf ("xyzzy\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/sysctl1.c b/sim/testsuite/sim/cris/c/sysctl1.c
new file mode 100644
index 00000000000..6646faca678
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/sysctl2.c b/sim/testsuite/sim/cris/c/sysctl2.c
new file mode 100644
index 00000000000..482e5463f81
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/sysctl2.c
@@ -0,0 +1,38 @@
+/* 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>
+
+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
+ };
+
+ syscall (SYS__sysctl, &scargs);
+ printf ("xyzzy\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/thread2.c b/sim/testsuite/sim/cris/c/thread2.c
new file mode 100644
index 00000000000..c9ad2f9214c
--- /dev/null
+++ b/sim/testsuite/sim/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, &param) != 0
+ || policy != SCHED_OTHER
+ || param.sched_priority != 0)
+ abort ();
+
+ if (pthread_setschedparam (pthread_self (), SCHED_OTHER, &param) != 0
+ || param.sched_priority != 0)
+ abort ();
+
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/sim/testsuite/sim/cris/c/thread3.c b/sim/testsuite/sim/cris/c/thread3.c
new file mode 100644
index 00000000000..3b6945ad3c3
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/thread4.c b/sim/testsuite/sim/cris/c/thread4.c
new file mode 100644
index 00000000000..cfa23279c50
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/thread5.c b/sim/testsuite/sim/cris/c/thread5.c
new file mode 100644
index 00000000000..494251fdd39
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/time1.c b/sim/testsuite/sim/cris/c/time1.c
new file mode 100644
index 00000000000..3fcf0e15352
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/truncate1.c b/sim/testsuite/sim/cris/c/truncate1.c
new file mode 100644
index 00000000000..477dc3d61d2
--- /dev/null
+++ b/sim/testsuite/sim/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/sim/cris/c/truncate2.c b/sim/testsuite/sim/cris/c/truncate2.c
new file mode 100644
index 00000000000..a4c6470d8c7
--- /dev/null
+++ b/sim/testsuite/sim/cris/c/truncate2.c
@@ -0,0 +1,6 @@
+/*
+#sim: --sysroot=@exedir@
+#notarget: cris*-*-elf
+*/
+#define PREFIX "/"
+#include "truncate1.c"
diff --git a/sim/testsuite/sim/cris/c/ugetrlimit1.c b/sim/testsuite/sim/cris/c/ugetrlimit1.c
new file mode 100644
index 00000000000..2a49b9589ee
--- /dev/null
+++ b/sim/testsuite/sim/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);
+}