* cris/traps.c (TARGET_SYS_writev): New macro.
[external/binutils.git] / sim / cris / traps.c
1 /* CRIS exception, interrupt, and trap (EIT) support
2    Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
3    Contributed by Axis Communications.
4
5 This file is part of the GNU simulators.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "sim-main.h"
21 #include "sim-options.h"
22 #include "bfd.h"
23 /* FIXME: get rid of targ-vals.h usage everywhere else.  */
24
25 #include <stdarg.h>
26 #ifdef HAVE_ERRNO_H
27 #include <errno.h>
28 #endif
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #ifdef HAVE_FCNTL_H
33 #include <fcntl.h>
34 #endif
35 #ifdef HAVE_SYS_PARAM_H
36 #include <sys/param.h>
37 #endif
38 #ifdef HAVE_SYS_STAT_H
39 #include <sys/stat.h>
40 #endif
41 /* For PATH_MAX, originally. */
42 #ifdef HAVE_LIMITS_H
43 #include <limits.h>
44 #endif
45
46 /* From ld/sysdep.h.  */
47 #ifdef PATH_MAX
48 # define SIM_PATHMAX PATH_MAX
49 #else
50 # ifdef MAXPATHLEN
51 #  define SIM_PATHMAX MAXPATHLEN
52 # else
53 #  define SIM_PATHMAX 1024
54 # endif
55 #endif
56
57 /* The verbatim values are from asm-cris/unistd.h.  */
58
59 #define TARGET_SYS_exit 1
60 #define TARGET_SYS_read 3
61 #define TARGET_SYS_write 4
62 #define TARGET_SYS_open 5
63 #define TARGET_SYS_close 6
64 #define TARGET_SYS_unlink 10
65 #define TARGET_SYS_time 13
66 #define TARGET_SYS_lseek 19
67 #define TARGET_SYS_getpid 20
68 #define TARGET_SYS_kill 37
69 #define TARGET_SYS_rename 38
70 #define TARGET_SYS_pipe 42
71 #define TARGET_SYS_brk 45
72 #define TARGET_SYS_ioctl 54
73 #define TARGET_SYS_fcntl 55
74 #define TARGET_SYS_getppid 64
75 #define TARGET_SYS_setrlimit 75
76 #define TARGET_SYS_gettimeofday  78
77 #define TARGET_SYS_readlink 85
78 #define TARGET_SYS_munmap 91
79 #define TARGET_SYS_truncate 92
80 #define TARGET_SYS_ftruncate 93
81 #define TARGET_SYS_socketcall 102
82 #define TARGET_SYS_stat 106
83 #define TARGET_SYS_fstat 108
84 #define TARGET_SYS_wait4 114
85 #define TARGET_SYS_sigreturn 119
86 #define TARGET_SYS_clone 120
87 #define TARGET_SYS_uname 122
88 #define TARGET_SYS_mprotect 125
89 #define TARGET_SYS_llseek 140
90 #define TARGET_SYS_writev 146
91 #define TARGET_SYS__sysctl 149
92 #define TARGET_SYS_sched_setparam 154
93 #define TARGET_SYS_sched_getparam 155
94 #define TARGET_SYS_sched_setscheduler 156
95 #define TARGET_SYS_sched_getscheduler 157
96 #define TARGET_SYS_sched_yield 158
97 #define TARGET_SYS_sched_get_priority_max 159
98 #define TARGET_SYS_sched_get_priority_min 160
99 #define TARGET_SYS_mremap 163
100 #define TARGET_SYS_poll 168
101 #define TARGET_SYS_rt_sigaction 174
102 #define TARGET_SYS_rt_sigprocmask 175
103 #define TARGET_SYS_rt_sigsuspend 179
104 #define TARGET_SYS_getcwd 183
105 #define TARGET_SYS_ugetrlimit 191
106 #define TARGET_SYS_mmap2 192
107 #define TARGET_SYS_stat64 195
108 #define TARGET_SYS_lstat64 196
109 #define TARGET_SYS_fstat64 197
110 #define TARGET_SYS_geteuid32 201
111 #define TARGET_SYS_getuid32 199
112 #define TARGET_SYS_getegid32 202
113 #define TARGET_SYS_getgid32 200
114 #define TARGET_SYS_fcntl64 221
115
116 #define TARGET_PROT_READ        0x1
117 #define TARGET_PROT_WRITE       0x2
118 #define TARGET_PROT_EXEC        0x4
119 #define TARGET_PROT_NONE        0x0
120
121 #define TARGET_MAP_SHARED       0x01
122 #define TARGET_MAP_PRIVATE      0x02
123 #define TARGET_MAP_TYPE         0x0f
124 #define TARGET_MAP_FIXED        0x10
125 #define TARGET_MAP_ANONYMOUS    0x20
126
127 #define TARGET_CTL_KERN         1
128 #define TARGET_CTL_VM           2
129 #define TARGET_CTL_NET          3
130 #define TARGET_CTL_PROC         4
131 #define TARGET_CTL_FS           5
132 #define TARGET_CTL_DEBUG        6
133 #define TARGET_CTL_DEV          7
134 #define TARGET_CTL_BUS          8
135 #define TARGET_CTL_ABI          9
136
137 #define TARGET_CTL_KERN_VERSION 4
138
139 /* linux/mman.h */
140 #define TARGET_MREMAP_MAYMOVE  1
141 #define TARGET_MREMAP_FIXED    2
142
143 #define TARGET_TCGETS 0x5401
144
145 #define TARGET_UTSNAME "#38 Sun Apr 1 00:00:00 MET 2001"
146
147 /* Seconds since the above date + 10 minutes.  */
148 #define TARGET_EPOCH 986080200
149
150 /* Milliseconds since start of run.  We use the number of syscalls to
151    avoid introducing noise in the execution time.  */
152 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
153
154 /* Seconds as in time(2).  */
155 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
156
157 #define TARGET_SCHED_OTHER 0
158
159 #define TARGET_RLIMIT_STACK 3
160 #define TARGET_RLIMIT_NOFILE 7
161
162 #define SIM_TARGET_MAX_THREADS 64
163 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
164
165 /* From linux/sched.h.  */
166 #define TARGET_CSIGNAL 0x000000ff
167 #define TARGET_CLONE_VM 0x00000100
168 #define TARGET_CLONE_FS 0x00000200
169 #define TARGET_CLONE_FILES 0x00000400
170 #define TARGET_CLONE_SIGHAND 0x00000800
171 #define TARGET_CLONE_PID 0x00001000
172 #define TARGET_CLONE_PTRACE 0x00002000
173 #define TARGET_CLONE_VFORK 0x00004000
174 #define TARGET_CLONE_PARENT 0x00008000
175 #define TARGET_CLONE_THREAD 0x00010000
176 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
177
178 /* From asm-cris/poll.h.  */
179 #define TARGET_POLLIN 1
180
181 /* From asm-cris/signal.h.  */
182 #define TARGET_SIG_BLOCK 0
183 #define TARGET_SIG_UNBLOCK 1
184 #define TARGET_SIG_SETMASK 2
185
186 #define TARGET_SIG_DFL 0
187 #define TARGET_SIG_IGN 1
188 #define TARGET_SIG_ERR ((USI)-1)
189
190 #define TARGET_SIGHUP 1
191 #define TARGET_SIGINT 2
192 #define TARGET_SIGQUIT 3
193 #define TARGET_SIGILL 4
194 #define TARGET_SIGTRAP 5
195 #define TARGET_SIGABRT 6
196 #define TARGET_SIGIOT 6
197 #define TARGET_SIGBUS 7
198 #define TARGET_SIGFPE 8
199 #define TARGET_SIGKILL 9
200 #define TARGET_SIGUSR1 10
201 #define TARGET_SIGSEGV 11
202 #define TARGET_SIGUSR2 12
203 #define TARGET_SIGPIPE 13
204 #define TARGET_SIGALRM 14
205 #define TARGET_SIGTERM 15
206 #define TARGET_SIGSTKFLT 16
207 #define TARGET_SIGCHLD 17
208 #define TARGET_SIGCONT 18
209 #define TARGET_SIGSTOP 19
210 #define TARGET_SIGTSTP 20
211 #define TARGET_SIGTTIN 21
212 #define TARGET_SIGTTOU 22
213 #define TARGET_SIGURG 23
214 #define TARGET_SIGXCPU 24
215 #define TARGET_SIGXFSZ 25
216 #define TARGET_SIGVTALRM 26
217 #define TARGET_SIGPROF 27
218 #define TARGET_SIGWINCH 28
219 #define TARGET_SIGIO 29
220 #define TARGET_SIGPOLL SIGIO
221 /* Actually commented out in the kernel header.  */
222 #define TARGET_SIGLOST 29
223 #define TARGET_SIGPWR 30
224 #define TARGET_SIGSYS 31
225
226 /* From include/asm-cris/signal.h.  */
227 #define TARGET_SA_NOCLDSTOP 0x00000001
228 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
229 #define TARGET_SA_SIGINFO 0x00000004
230 #define TARGET_SA_ONSTACK 0x08000000
231 #define TARGET_SA_RESTART 0x10000000
232 #define TARGET_SA_NODEFER 0x40000000
233 #define TARGET_SA_RESETHAND 0x80000000
234 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
235 #define TARGET_SA_RESTORER 0x04000000
236
237 /* From linux/wait.h.  */
238 #define TARGET_WNOHANG 1
239 #define TARGET_WUNTRACED 2
240 #define TARGET___WNOTHREAD 0x20000000
241 #define TARGET___WALL 0x40000000
242 #define TARGET___WCLONE 0x80000000
243
244 /* From linux/limits.h. */
245 #define TARGET_PIPE_BUF 4096
246
247 static const char stat_map[] =
248 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
249 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
250 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
251 ":st_ino,8";
252
253 static const CB_TARGET_DEFS_MAP syscall_map[] =
254 {
255   { CB_SYS_open, TARGET_SYS_open },
256   { CB_SYS_close, TARGET_SYS_close },
257   { CB_SYS_read, TARGET_SYS_read },
258   { CB_SYS_write, TARGET_SYS_write },
259   { CB_SYS_lseek, TARGET_SYS_lseek },
260   { CB_SYS_unlink, TARGET_SYS_unlink },
261   { CB_SYS_getpid, TARGET_SYS_getpid },
262   { CB_SYS_fstat, TARGET_SYS_fstat64 },
263   { CB_SYS_lstat, TARGET_SYS_lstat64 },
264   { CB_SYS_stat, TARGET_SYS_stat64 },
265   { CB_SYS_pipe, TARGET_SYS_pipe },
266   { CB_SYS_rename, TARGET_SYS_rename },
267   { CB_SYS_truncate, TARGET_SYS_truncate },
268   { CB_SYS_ftruncate, TARGET_SYS_ftruncate },
269   { 0, -1 }
270 };
271
272 /* An older, 32-bit-only stat mapping.  */
273 static const char stat32_map[] =
274 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
275 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
276 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
277
278 /* Map for calls using the 32-bit struct stat.  Primarily used by the
279    newlib Linux mapping.  */
280 static const CB_TARGET_DEFS_MAP syscall_stat32_map[] =
281 {
282   { CB_SYS_fstat, TARGET_SYS_fstat },
283   { CB_SYS_stat, TARGET_SYS_stat },
284   { 0, -1 }
285 };
286
287 /* Giving the true value for the running sim process will lead to
288    non-time-invariant behavior.  */
289 #define TARGET_PID 42
290
291 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
292    we did, we'd still don't get a register number with the "16" offset.  */
293 #define TARGET_SRP_REGNUM (16+11)
294
295 /* Extracted by applying
296    awk '/^#define/ { printf "#ifdef %s\n  { %s, %s },\n#endif\n", $2, $2, $3;}'
297    on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
298    adjusting the synonyms.  */
299
300 static const CB_TARGET_DEFS_MAP errno_map[] =
301 {
302 #ifdef EPERM
303   { EPERM, 1 },
304 #endif
305 #ifdef ENOENT
306   { ENOENT, 2 },
307 #endif
308 #ifdef ESRCH
309   { ESRCH, 3 },
310 #endif
311 #ifdef EINTR
312   { EINTR, 4 },
313 #endif
314 #ifdef EIO
315   { EIO, 5 },
316 #endif
317 #ifdef ENXIO
318   { ENXIO, 6 },
319 #endif
320 #ifdef E2BIG
321   { E2BIG, 7 },
322 #endif
323 #ifdef ENOEXEC
324   { ENOEXEC, 8 },
325 #endif
326 #ifdef EBADF
327   { EBADF, 9 },
328 #endif
329 #ifdef ECHILD
330   { ECHILD, 10 },
331 #endif
332 #ifdef EAGAIN
333   { EAGAIN, 11 },
334 #endif
335 #ifdef ENOMEM
336   { ENOMEM, 12 },
337 #endif
338 #ifdef EACCES
339   { EACCES, 13 },
340 #endif
341 #ifdef EFAULT
342   { EFAULT, 14 },
343 #endif
344 #ifdef ENOTBLK
345   { ENOTBLK, 15 },
346 #endif
347 #ifdef EBUSY
348   { EBUSY, 16 },
349 #endif
350 #ifdef EEXIST
351   { EEXIST, 17 },
352 #endif
353 #ifdef EXDEV
354   { EXDEV, 18 },
355 #endif
356 #ifdef ENODEV
357   { ENODEV, 19 },
358 #endif
359 #ifdef ENOTDIR
360   { ENOTDIR, 20 },
361 #endif
362 #ifdef EISDIR
363   { EISDIR, 21 },
364 #endif
365 #ifdef EINVAL
366   { EINVAL, 22 },
367 #endif
368 #ifdef ENFILE
369   { ENFILE, 23 },
370 #endif
371 #ifdef EMFILE
372   { EMFILE, 24 },
373 #endif
374 #ifdef ENOTTY
375   { ENOTTY, 25 },
376 #endif
377 #ifdef ETXTBSY
378   { ETXTBSY, 26 },
379 #endif
380 #ifdef EFBIG
381   { EFBIG, 27 },
382 #endif
383 #ifdef ENOSPC
384   { ENOSPC, 28 },
385 #endif
386 #ifdef ESPIPE
387   { ESPIPE, 29 },
388 #endif
389 #ifdef EROFS
390   { EROFS, 30 },
391 #endif
392 #ifdef EMLINK
393   { EMLINK, 31 },
394 #endif
395 #ifdef EPIPE
396   { EPIPE, 32 },
397 #endif
398 #ifdef EDOM
399   { EDOM, 33 },
400 #endif
401 #ifdef ERANGE
402   { ERANGE, 34 },
403 #endif
404 #ifdef EDEADLK
405   { EDEADLK, 35 },
406 #endif
407 #ifdef ENAMETOOLONG
408   { ENAMETOOLONG, 36 },
409 #endif
410 #ifdef ENOLCK
411   { ENOLCK, 37 },
412 #endif
413 #ifdef ENOSYS
414   { ENOSYS, 38 },
415 #endif
416 #ifdef ENOTEMPTY
417   { ENOTEMPTY, 39 },
418 #endif
419 #ifdef ELOOP
420   { ELOOP, 40 },
421 #endif
422 #ifdef EWOULDBLOCK
423   { EWOULDBLOCK, 11 },
424 #endif
425 #ifdef ENOMSG
426   { ENOMSG, 42 },
427 #endif
428 #ifdef EIDRM
429   { EIDRM, 43 },
430 #endif
431 #ifdef ECHRNG
432   { ECHRNG, 44 },
433 #endif
434 #ifdef EL2NSYNC
435   { EL2NSYNC, 45 },
436 #endif
437 #ifdef EL3HLT
438   { EL3HLT, 46 },
439 #endif
440 #ifdef EL3RST
441   { EL3RST, 47 },
442 #endif
443 #ifdef ELNRNG
444   { ELNRNG, 48 },
445 #endif
446 #ifdef EUNATCH
447   { EUNATCH, 49 },
448 #endif
449 #ifdef ENOCSI
450   { ENOCSI, 50 },
451 #endif
452 #ifdef EL2HLT
453   { EL2HLT, 51 },
454 #endif
455 #ifdef EBADE
456   { EBADE, 52 },
457 #endif
458 #ifdef EBADR
459   { EBADR, 53 },
460 #endif
461 #ifdef EXFULL
462   { EXFULL, 54 },
463 #endif
464 #ifdef ENOANO
465   { ENOANO, 55 },
466 #endif
467 #ifdef EBADRQC
468   { EBADRQC, 56 },
469 #endif
470 #ifdef EBADSLT
471   { EBADSLT, 57 },
472 #endif
473 #ifdef EDEADLOCK
474   { EDEADLOCK, 35 },
475 #endif
476 #ifdef EBFONT
477   { EBFONT, 59 },
478 #endif
479 #ifdef ENOSTR
480   { ENOSTR, 60 },
481 #endif
482 #ifdef ENODATA
483   { ENODATA, 61 },
484 #endif
485 #ifdef ETIME
486   { ETIME, 62 },
487 #endif
488 #ifdef ENOSR
489   { ENOSR, 63 },
490 #endif
491 #ifdef ENONET
492   { ENONET, 64 },
493 #endif
494 #ifdef ENOPKG
495   { ENOPKG, 65 },
496 #endif
497 #ifdef EREMOTE
498   { EREMOTE, 66 },
499 #endif
500 #ifdef ENOLINK
501   { ENOLINK, 67 },
502 #endif
503 #ifdef EADV
504   { EADV, 68 },
505 #endif
506 #ifdef ESRMNT
507   { ESRMNT, 69 },
508 #endif
509 #ifdef ECOMM
510   { ECOMM, 70 },
511 #endif
512 #ifdef EPROTO
513   { EPROTO, 71 },
514 #endif
515 #ifdef EMULTIHOP
516   { EMULTIHOP, 72 },
517 #endif
518 #ifdef EDOTDOT
519   { EDOTDOT, 73 },
520 #endif
521 #ifdef EBADMSG
522   { EBADMSG, 74 },
523 #endif
524 #ifdef EOVERFLOW
525   { EOVERFLOW, 75 },
526 #endif
527 #ifdef ENOTUNIQ
528   { ENOTUNIQ, 76 },
529 #endif
530 #ifdef EBADFD
531   { EBADFD, 77 },
532 #endif
533 #ifdef EREMCHG
534   { EREMCHG, 78 },
535 #endif
536 #ifdef ELIBACC
537   { ELIBACC, 79 },
538 #endif
539 #ifdef ELIBBAD
540   { ELIBBAD, 80 },
541 #endif
542 #ifdef ELIBSCN
543   { ELIBSCN, 81 },
544 #endif
545 #ifdef ELIBMAX
546   { ELIBMAX, 82 },
547 #endif
548 #ifdef ELIBEXEC
549   { ELIBEXEC, 83 },
550 #endif
551 #ifdef EILSEQ
552   { EILSEQ, 84 },
553 #endif
554 #ifdef ERESTART
555   { ERESTART, 85 },
556 #endif
557 #ifdef ESTRPIPE
558   { ESTRPIPE, 86 },
559 #endif
560 #ifdef EUSERS
561   { EUSERS, 87 },
562 #endif
563 #ifdef ENOTSOCK
564   { ENOTSOCK, 88 },
565 #endif
566 #ifdef EDESTADDRREQ
567   { EDESTADDRREQ, 89 },
568 #endif
569 #ifdef EMSGSIZE
570   { EMSGSIZE, 90 },
571 #endif
572 #ifdef EPROTOTYPE
573   { EPROTOTYPE, 91 },
574 #endif
575 #ifdef ENOPROTOOPT
576   { ENOPROTOOPT, 92 },
577 #endif
578 #ifdef EPROTONOSUPPORT
579   { EPROTONOSUPPORT, 93 },
580 #endif
581 #ifdef ESOCKTNOSUPPORT
582   { ESOCKTNOSUPPORT, 94 },
583 #endif
584 #ifdef EOPNOTSUPP
585   { EOPNOTSUPP, 95 },
586 #endif
587 #ifdef EPFNOSUPPORT
588   { EPFNOSUPPORT, 96 },
589 #endif
590 #ifdef EAFNOSUPPORT
591   { EAFNOSUPPORT, 97 },
592 #endif
593 #ifdef EADDRINUSE
594   { EADDRINUSE, 98 },
595 #endif
596 #ifdef EADDRNOTAVAIL
597   { EADDRNOTAVAIL, 99 },
598 #endif
599 #ifdef ENETDOWN
600   { ENETDOWN, 100 },
601 #endif
602 #ifdef ENETUNREACH
603   { ENETUNREACH, 101 },
604 #endif
605 #ifdef ENETRESET
606   { ENETRESET, 102 },
607 #endif
608 #ifdef ECONNABORTED
609   { ECONNABORTED, 103 },
610 #endif
611 #ifdef ECONNRESET
612   { ECONNRESET, 104 },
613 #endif
614 #ifdef ENOBUFS
615   { ENOBUFS, 105 },
616 #endif
617 #ifdef EISCONN
618   { EISCONN, 106 },
619 #endif
620 #ifdef ENOTCONN
621   { ENOTCONN, 107 },
622 #endif
623 #ifdef ESHUTDOWN
624   { ESHUTDOWN, 108 },
625 #endif
626 #ifdef ETOOMANYREFS
627   { ETOOMANYREFS, 109 },
628 #endif
629 #ifdef ETIMEDOUT
630   { ETIMEDOUT, 110 },
631 #endif
632 #ifdef ECONNREFUSED
633   { ECONNREFUSED, 111 },
634 #endif
635 #ifdef EHOSTDOWN
636   { EHOSTDOWN, 112 },
637 #endif
638 #ifdef EHOSTUNREACH
639   { EHOSTUNREACH, 113 },
640 #endif
641 #ifdef EALREADY
642   { EALREADY, 114 },
643 #endif
644 #ifdef EINPROGRESS
645   { EINPROGRESS, 115 },
646 #endif
647 #ifdef ESTALE
648   { ESTALE, 116 },
649 #endif
650 #ifdef EUCLEAN
651   { EUCLEAN, 117 },
652 #endif
653 #ifdef ENOTNAM
654   { ENOTNAM, 118 },
655 #endif
656 #ifdef ENAVAIL
657   { ENAVAIL, 119 },
658 #endif
659 #ifdef EISNAM
660   { EISNAM, 120 },
661 #endif
662 #ifdef EREMOTEIO
663   { EREMOTEIO, 121 },
664 #endif
665 #ifdef EDQUOT
666   { EDQUOT, 122 },
667 #endif
668 #ifdef ENOMEDIUM
669   { ENOMEDIUM, 123 },
670 #endif
671 #ifdef EMEDIUMTYPE
672   { EMEDIUMTYPE, 124 },
673 #endif
674   { 0, -1 }
675 };
676
677 /* Extracted by applying
678    perl -ne 'if ($_ =~ /^#define/) { split;
679      printf "#ifdef $_[1]\n  { %s, 0x%x },\n#endif\n",
680              $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
681    on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
682    installation and removing synonyms and unnecessary items.  Don't
683    forget the end-marker.  */
684
685 /* These we treat specially, as they're used in the fcntl F_GETFL
686    syscall.  For consistency, open_map is also manually edited to use
687    these macros.  */
688 #define TARGET_O_ACCMODE 0x3
689 #define TARGET_O_RDONLY 0x0
690 #define TARGET_O_WRONLY 0x1
691
692 static const CB_TARGET_DEFS_MAP open_map[] = {
693 #ifdef O_ACCMODE
694   { O_ACCMODE, TARGET_O_ACCMODE },
695 #endif
696 #ifdef O_RDONLY
697   { O_RDONLY, TARGET_O_RDONLY },
698 #endif
699 #ifdef O_WRONLY
700   { O_WRONLY, TARGET_O_WRONLY },
701 #endif
702 #ifdef O_RDWR
703   { O_RDWR, 0x2 },
704 #endif
705 #ifdef O_CREAT
706   { O_CREAT, 0x40 },
707 #endif
708 #ifdef O_EXCL
709   { O_EXCL, 0x80 },
710 #endif
711 #ifdef O_NOCTTY
712   { O_NOCTTY, 0x100 },
713 #endif
714 #ifdef O_TRUNC
715   { O_TRUNC, 0x200 },
716 #endif
717 #ifdef O_APPEND
718   { O_APPEND, 0x400 },
719 #endif
720 #ifdef O_NONBLOCK
721   { O_NONBLOCK, 0x800 },
722 #endif
723 #ifdef O_NDELAY
724   { O_NDELAY, 0x0 },
725 #endif
726 #ifdef O_SYNC
727   { O_SYNC, 0x1000 },
728 #endif
729 #ifdef FASYNC
730   { FASYNC, 0x2000 },
731 #endif
732 #ifdef O_DIRECT
733   { O_DIRECT, 0x4000 },
734 #endif
735 #ifdef O_LARGEFILE
736   { O_LARGEFILE, 0x8000 },
737 #endif
738 #ifdef O_DIRECTORY
739   { O_DIRECTORY, 0x10000 },
740 #endif
741 #ifdef O_NOFOLLOW
742   { O_NOFOLLOW, 0x20000 },
743 #endif
744   { -1, -1 }
745 };
746
747 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls.  */
748 static SIM_CPU *current_cpu_for_cb_callback;
749
750 static int syscall_read_mem (host_callback *, struct cb_syscall *,
751                              unsigned long, char *, int);
752 static int syscall_write_mem (host_callback *, struct cb_syscall *,
753                               unsigned long, const char *, int);
754 static USI create_map (SIM_DESC, struct cris_sim_mmapped_page **,
755                        USI addr, USI len);
756 static USI unmap_pages (SIM_DESC, struct cris_sim_mmapped_page **,
757                        USI addr, USI len);
758 static USI is_mapped (SIM_DESC, struct cris_sim_mmapped_page **,
759                        USI addr, USI len);
760 static void dump_statistics (SIM_CPU *current_cpu);
761 static void make_first_thread (SIM_CPU *current_cpu);
762
763 /* Read/write functions for system call interface.  */
764
765 static int
766 syscall_read_mem (host_callback *cb ATTRIBUTE_UNUSED,
767                   struct cb_syscall *sc,
768                   unsigned long taddr, char *buf, int bytes)
769 {
770   SIM_DESC sd = (SIM_DESC) sc->p1;
771   SIM_CPU *cpu = (SIM_CPU *) sc->p2;
772
773   return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
774 }
775
776 static int
777 syscall_write_mem (host_callback *cb ATTRIBUTE_UNUSED,
778                    struct cb_syscall *sc,
779                    unsigned long taddr, const char *buf, int bytes)
780 {
781   SIM_DESC sd = (SIM_DESC) sc->p1;
782   SIM_CPU *cpu = (SIM_CPU *) sc->p2;
783
784   return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
785 }
786
787 /* When we risk running self-modified code (as in trampolines), this is
788    called from special-case insns.  The silicon CRIS CPU:s have enough
789    cache snooping implemented making this a simulator-only issue.  Tests:
790    gcc.c-torture/execute/931002-1.c execution, -O3 -g
791    gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer.  */
792
793 void
794 cris_flush_simulator_decode_cache (SIM_CPU *current_cpu,
795                                    USI pc ATTRIBUTE_UNUSED)
796 {
797   SIM_DESC sd = CPU_STATE (current_cpu);
798
799 #if WITH_SCACHE
800   if (USING_SCACHE_P (sd))
801     scache_flush_cpu (current_cpu);
802 #endif
803 }
804
805 /* Output statistics at the end of a run.  */
806 static void
807 dump_statistics (SIM_CPU *current_cpu)
808 {
809   SIM_DESC sd = CPU_STATE (current_cpu);
810   CRIS_MISC_PROFILE *profp
811     = CPU_CRIS_MISC_PROFILE (current_cpu);
812   unsigned64 total = profp->basic_cycle_count;
813   const char *textmsg = "Basic clock cycles, total @: %llu\n";
814
815   /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
816      what's included in the "total" count only.  */
817   switch (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
818           & FLAG_CRIS_MISC_PROFILE_ALL)
819     {
820     case FLAG_CRIS_MISC_PROFILE_SIMPLE:
821       break;
822
823     case (FLAG_CRIS_MISC_PROFILE_UNALIGNED | FLAG_CRIS_MISC_PROFILE_SIMPLE):
824       textmsg
825         = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
826       total += profp->unaligned_mem_dword_count;
827       break;
828
829     case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE | FLAG_CRIS_MISC_PROFILE_SIMPLE):
830       textmsg = "Schedulable clock cycles, total @: %llu\n";
831       total
832         += (profp->memsrc_stall_count
833             + profp->memraw_stall_count
834             + profp->movemsrc_stall_count
835             + profp->movemdst_stall_count
836             + profp->mulsrc_stall_count
837             + profp->jumpsrc_stall_count
838             + profp->unaligned_mem_dword_count);
839       break;
840
841     case FLAG_CRIS_MISC_PROFILE_ALL:
842       textmsg = "All accounted clock cycles, total @: %llu\n";
843       total
844         += (profp->memsrc_stall_count
845             + profp->memraw_stall_count
846             + profp->movemsrc_stall_count
847             + profp->movemdst_stall_count
848             + profp->movemaddr_stall_count
849             + profp->mulsrc_stall_count
850             + profp->jumpsrc_stall_count
851             + profp->branch_stall_count
852             + profp->jumptarget_stall_count
853             + profp->unaligned_mem_dword_count);
854       break;
855
856     default:
857       abort ();
858
859       sim_io_eprintf (sd,
860                       "Internal inconsistency at %s:%d",
861                       __FILE__, __LINE__);
862       sim_engine_halt (sd, current_cpu, NULL, 0,
863                        sim_stopped, SIM_SIGILL);
864     }
865
866   /* Historically, these messages have gone to stderr, so we'll keep it
867      that way.  It's also easier to then tell it from normal program
868      output.  FIXME: Add redirect option like "run -e file".  */
869   sim_io_eprintf (sd, textmsg, total);
870
871   /* For v32, unaligned_mem_dword_count should always be 0.  For
872      v10, memsrc_stall_count should always be 0.  */
873   sim_io_eprintf (sd, "Memory source stall cycles: %llu\n",
874                   (unsigned long long) (profp->memsrc_stall_count
875                                         + profp->unaligned_mem_dword_count));
876   sim_io_eprintf (sd, "Memory read-after-write stall cycles: %llu\n",
877                   (unsigned long long) profp->memraw_stall_count);
878   sim_io_eprintf (sd, "Movem source stall cycles: %llu\n",
879                   (unsigned long long) profp->movemsrc_stall_count);
880   sim_io_eprintf (sd, "Movem destination stall cycles: %llu\n",
881                   (unsigned long long) profp->movemdst_stall_count);
882   sim_io_eprintf (sd, "Movem address stall cycles: %llu\n",
883                   (unsigned long long) profp->movemaddr_stall_count);
884   sim_io_eprintf (sd, "Multiplication source stall cycles: %llu\n",
885                   (unsigned long long) profp->mulsrc_stall_count);
886   sim_io_eprintf (sd, "Jump source stall cycles: %llu\n",
887                   (unsigned long long) profp->jumpsrc_stall_count);
888   sim_io_eprintf (sd, "Branch misprediction stall cycles: %llu\n",
889                   (unsigned long long) profp->branch_stall_count);
890   sim_io_eprintf (sd, "Jump target stall cycles: %llu\n",
891                   (unsigned long long) profp->jumptarget_stall_count);
892 }
893
894 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
895    Return 1 if a overlap detected, 0 otherwise.  */
896
897 static USI
898 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED,
899            struct cris_sim_mmapped_page **rootp,
900            USI addr, USI len)
901 {
902   struct cris_sim_mmapped_page *mapp;
903
904   if (len == 0 || (len & 8191))
905     abort ();
906
907   /* Iterate over the reverse-address sorted pages until we find a page in
908      or lower than the checked area.  */
909   for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
910     if (mapp->addr < addr + len && mapp->addr >= addr)
911       return 1;
912
913   return 0;
914 }
915
916 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
917    Return 1 if the whole area is mapped, 0 otherwise.  */
918
919 static USI
920 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED,
921                 struct cris_sim_mmapped_page **rootp,
922                 USI addr, USI len)
923 {
924   struct cris_sim_mmapped_page *mapp;
925
926   if (len == 0 || (len & 8191))
927     abort ();
928
929   /* Iterate over the reverse-address sorted pages until we find a page
930      lower than the checked area.  */
931   for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
932     if (addr == mapp->addr && len == 8192)
933       return 1;
934     else if (addr + len > mapp->addr)
935       len -= 8192;
936
937   return 0;
938 }
939
940 /* Debug helper; to be run from gdb.  */
941
942 void
943 cris_dump_map (SIM_CPU *current_cpu)
944 {
945   struct cris_sim_mmapped_page *mapp;
946   USI start, end;
947
948   for (mapp = current_cpu->highest_mmapped_page,
949          start = mapp == NULL ? 0 : mapp->addr + 8192,
950          end = mapp == NULL ? 0 : mapp->addr + 8191;
951        mapp != NULL;
952        mapp = mapp->prev)
953     {
954       if (mapp->addr != start - 8192)
955         {
956           sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
957           end = mapp->addr + 8191;
958         }
959
960       start = mapp->addr;
961     }
962
963   if (current_cpu->highest_mmapped_page != NULL)
964     sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
965 }
966
967 /* Create mmapped memory.  */
968
969 static USI
970 create_map (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
971             USI len)
972 {
973   struct cris_sim_mmapped_page *mapp;
974   struct cris_sim_mmapped_page **higher_prevp = rootp;
975   USI new_addr = 0x40000000;
976
977   if (addr != 0)
978     new_addr = addr;
979   else if (*rootp)
980     new_addr = rootp[0]->addr + 8192;
981
982   if (len != 8192)
983     {
984       USI page_addr;
985
986       if (len & 8191)
987         /* Which is better: return an error for this, or just round it up?  */
988         abort ();
989
990       /* Do a recursive call for each page in the request.  */
991       for (page_addr = new_addr; len != 0; page_addr += 8192, len -= 8192)
992         if (create_map (sd, rootp, page_addr, 8192) >= (USI) -8191)
993           abort ();
994
995       return new_addr;
996     }
997
998   for (mapp = *rootp;
999        mapp != NULL && mapp->addr > new_addr;
1000        mapp = mapp->prev)
1001     higher_prevp = &mapp->prev;
1002
1003   /* Allocate the new page, on the next higher page from the last one
1004      allocated, and link in the new descriptor before previous ones.  */
1005   mapp = malloc (sizeof (*mapp));
1006
1007   if (mapp == NULL)
1008     return (USI) -ENOMEM;
1009
1010   sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
1011                    new_addr, len,
1012                    0, NULL, NULL);
1013
1014   mapp->addr = new_addr;
1015   mapp->prev = *higher_prevp;
1016   *higher_prevp = mapp;
1017
1018   return new_addr;
1019 }
1020
1021 /* Unmap one or more pages.  */
1022
1023 static USI
1024 unmap_pages (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
1025             USI len)
1026 {
1027   struct cris_sim_mmapped_page *mapp;
1028   struct cris_sim_mmapped_page **higher_prevp = rootp;
1029
1030   if (len != 8192)
1031     {
1032       USI page_addr;
1033
1034       if (len & 8191)
1035         /* Which is better: return an error for this, or just round it up?  */
1036         abort ();
1037
1038       /* Loop backwards to make each call is O(1) over the number of pages
1039          allocated, if we're unmapping from the high end of the pages.  */
1040       for (page_addr = addr + len - 8192;
1041            page_addr >= addr;
1042            page_addr -= 8192)
1043         if (unmap_pages (sd, rootp, page_addr, 8192) != 0)
1044           abort ();
1045
1046       return 0;
1047     }
1048
1049   for (mapp = *rootp; mapp != NULL && mapp->addr > addr; mapp = mapp->prev)
1050     higher_prevp = &mapp->prev;
1051
1052   if (mapp == NULL || mapp->addr != addr)
1053     return EINVAL;
1054
1055   *higher_prevp = mapp->prev;
1056   sim_core_detach (sd, NULL, 0, 0, addr);
1057   free (mapp);
1058   return 0;
1059 }
1060
1061 /* The semantic code invokes this for illegal (unrecognized) instructions.  */
1062
1063 SEM_PC
1064 sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
1065 {
1066   SIM_DESC sd = CPU_STATE (current_cpu);
1067
1068   sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
1069   return vpc;
1070 }
1071
1072 /* Handlers from the CGEN description that should not be called.  */
1073
1074 USI
1075 cris_bmod_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
1076                    UINT srcreg ATTRIBUTE_UNUSED,
1077                    USI dstreg ATTRIBUTE_UNUSED)
1078 {
1079   abort ();
1080 }
1081
1082 void
1083 h_supr_set_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
1084                     UINT index ATTRIBUTE_UNUSED,
1085                     USI page ATTRIBUTE_UNUSED,
1086                     USI newval ATTRIBUTE_UNUSED)
1087 {
1088   abort ();
1089 }
1090
1091 USI
1092 h_supr_get_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
1093                     UINT index ATTRIBUTE_UNUSED,
1094                     USI page ATTRIBUTE_UNUSED)
1095 {
1096   abort ();
1097 }
1098
1099 /* Swap one context for another.  */
1100
1101 static void
1102 schedule (SIM_CPU *current_cpu, int next)
1103 {
1104   /* Need to mark context-switches in the trace output.  */
1105   if ((CPU_CRIS_MISC_PROFILE (current_cpu)->flags
1106        & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE))
1107     cris_trace_printf (CPU_STATE (current_cpu), current_cpu,
1108                        "\t#:%d\n", next);
1109
1110   /* Copy the current context (if there is one) to its slot.  */
1111   if (current_cpu->thread_data[current_cpu->threadno].cpu_context)
1112     memcpy (current_cpu->thread_data[current_cpu->threadno].cpu_context,
1113             &current_cpu->cpu_data_placeholder,
1114             current_cpu->thread_cpu_data_size);
1115
1116   /* Copy the new context from its slot.  */
1117   memcpy (&current_cpu->cpu_data_placeholder,
1118           current_cpu->thread_data[next].cpu_context,
1119           current_cpu->thread_cpu_data_size);
1120
1121   /* Update needed stuff to indicate the new context.  */
1122   current_cpu->threadno = next;
1123
1124   /* Handle pending signals.  */
1125   if (current_cpu->thread_data[next].sigpending
1126       /* We don't run nested signal handlers.  This means that pause(2)
1127          and sigsuspend(2) do not work in sighandlers, but that
1128          shouldn't be too hard a restriction.  It also greatly
1129          simplifies the code.  */
1130       && current_cpu->thread_data[next].cpu_context_atsignal == NULL)
1131   {
1132     int sig;
1133
1134     /* See if there's really a pending, non-blocked handler.  We don't
1135        queue signals, so just use the first one in ascending order.  */
1136     for (sig = 0; sig < 64; sig++)
1137       if (current_cpu->thread_data[next].sigdata[sig].pending
1138           && !current_cpu->thread_data[next].sigdata[sig].blocked)
1139       {
1140         bfd_byte regbuf[4];
1141         USI sp;
1142         int i;
1143         USI blocked;
1144         USI pc = sim_pc_get (current_cpu);
1145
1146         /* It's simpler to save the CPU context inside the simulator
1147            than on the stack.  */
1148         current_cpu->thread_data[next].cpu_context_atsignal
1149           = (*current_cpu
1150              ->make_thread_cpu_data) (current_cpu,
1151                                       current_cpu->thread_data[next]
1152                                       .cpu_context);
1153
1154         (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
1155         sp = bfd_getl32 (regbuf);
1156
1157         /* Make sure we have an aligned stack.  */
1158         sp &= ~3;
1159
1160         /* Make room for the signal frame, aligned.  FIXME: Check that
1161            the memory exists, map it in if absent.  (BTW, should also
1162            implement on-access automatic stack allocation).  */
1163         sp -= 20;
1164
1165         /* This isn't the same signal frame as the kernel uses, because
1166            we don't want to bother getting all registers on and off the
1167            stack.  */
1168
1169         /* First, we store the currently blocked signals.  */
1170         blocked = 0;
1171         for (i = 0; i < 32; i++)
1172           blocked
1173             |= current_cpu->thread_data[next].sigdata[i + 1].blocked << i;
1174         sim_core_write_aligned_4 (current_cpu, pc, 0, sp, blocked);
1175         blocked = 0;
1176         for (i = 0; i < 31; i++)
1177           blocked
1178             |= current_cpu->thread_data[next].sigdata[i + 33].blocked << i;
1179         sim_core_write_aligned_4 (current_cpu, pc, 0, sp + 4, blocked);
1180
1181         /* Then, the actual instructions.  This is CPU-specific, but we
1182            use instructions from the common subset for v10 and v32 which
1183            should be safe for the time being but could be parametrized
1184            if need be.  */
1185         /* MOVU.W [PC+],R9.  */
1186         sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 8, 0x9c5f);
1187         /* .WORD TARGET_SYS_sigreturn.  */
1188         sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 10,
1189                                   TARGET_SYS_sigreturn);
1190         /* BREAK 13.  */
1191         sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 12, 0xe93d);
1192
1193         /* NOP (on v32; it's SETF on v10, but is the correct compatible
1194            instruction.  Still, it doesn't matter because v10 has no
1195            delay slot for BREAK so it will not be executed).  */
1196         sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 16, 0x05b0);
1197
1198         /* Modify registers to hold the right values for the sighandler
1199            context: updated stackpointer and return address pointing to
1200            the sigreturn stub.  */
1201         bfd_putl32 (sp, regbuf);
1202         (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
1203         bfd_putl32 (sp + 8, regbuf);
1204         (*CPU_REG_STORE (current_cpu)) (current_cpu, TARGET_SRP_REGNUM,
1205                                         regbuf, 4);
1206
1207         current_cpu->thread_data[next].sigdata[sig].pending = 0;
1208
1209         /* Block this signal (for the duration of the sighandler).  */
1210         current_cpu->thread_data[next].sigdata[sig].blocked = 1;
1211
1212         sim_pc_set (current_cpu, current_cpu->sighandler[sig]);
1213         bfd_putl32 (sig, regbuf);
1214         (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10,
1215                                         regbuf, 4);
1216
1217         /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1218            needed all this for, specifies a SA_SIGINFO call but treats it
1219            like an ordinary sighandler; only the signal number argument is
1220            inspected.  To make future need to implement SA_SIGINFO
1221            correctly possible, we set the siginfo argument register to a
1222            magic (hopefully non-address) number.  (NB: then, you should
1223            just need to pass the siginfo argument; it seems you probably
1224            don't need to implement the specific rt_sigreturn.)  */
1225         bfd_putl32 (0xbad5161f, regbuf);
1226         (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R11,
1227                                         regbuf, 4);
1228
1229         /* The third argument is unused and the kernel sets it to 0.  */
1230         bfd_putl32 (0, regbuf);
1231         (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R12,
1232                                         regbuf, 4);
1233         return;
1234       }
1235
1236     /* No, there actually was no pending signal for this thread.  Reset
1237        this flag.  */
1238     current_cpu->thread_data[next].sigpending = 0;
1239   }
1240 }
1241
1242 /* Reschedule the simplest possible way until something else is absolutely
1243    necessary:
1244    - A. Find the next process (round-robin) that doesn't have at_syscall
1245         set, schedule it.
1246    - B. If there is none, just run the next process, round-robin.
1247    - Clear at_syscall for the current process.  */
1248
1249 static void
1250 reschedule (SIM_CPU *current_cpu)
1251 {
1252   int i;
1253
1254   /* Iterate over all thread slots, because after a few thread creations
1255      and exits, we don't know where the live ones are.  */
1256   for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
1257        i != current_cpu->threadno;
1258        i = (i + 1) % SIM_TARGET_MAX_THREADS)
1259     if (current_cpu->thread_data[i].cpu_context
1260         && current_cpu->thread_data[i].at_syscall == 0)
1261       {
1262         schedule (current_cpu, i);
1263         return;
1264       }
1265
1266   /* Pick any next live thread.  */
1267   for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
1268        i != current_cpu->threadno;
1269        i = (i + 1) % SIM_TARGET_MAX_THREADS)
1270     if (current_cpu->thread_data[i].cpu_context)
1271       {
1272         schedule (current_cpu, i);
1273         return;
1274       }
1275
1276   /* More than one live thread, but we couldn't find the next one?  */
1277   abort ();
1278 }
1279
1280 /* Set up everything to receive (or IGN) an incoming signal to the
1281    current context.  */
1282
1283 static int
1284 deliver_signal (SIM_CPU *current_cpu, int sig, unsigned int pid)
1285 {
1286   int i;
1287   USI pc = sim_pc_get (current_cpu);
1288
1289   /* Find the thread index of the pid. */
1290   for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
1291     /* Apparently it's ok to send signals to zombies (so a check for
1292        current_cpu->thread_data[i].cpu_context != NULL would be
1293        wrong). */
1294     if (current_cpu->thread_data[i].threadid == pid - TARGET_PID)
1295       {
1296         if (sig < 64)
1297           switch (current_cpu->sighandler[sig])
1298             {
1299             case TARGET_SIG_DFL:
1300               switch (sig)
1301                 {
1302                   /* The following according to the glibc
1303                      documentation. (The kernel code has non-obvious
1304                      execution paths.)  */
1305                 case TARGET_SIGFPE:
1306                 case TARGET_SIGILL:
1307                 case TARGET_SIGSEGV:
1308                 case TARGET_SIGBUS:
1309                 case TARGET_SIGABRT:
1310                 case TARGET_SIGTRAP:
1311                 case TARGET_SIGSYS:
1312
1313                 case TARGET_SIGTERM:
1314                 case TARGET_SIGINT:
1315                 case TARGET_SIGQUIT:
1316                 case TARGET_SIGKILL:
1317                 case TARGET_SIGHUP:
1318
1319                 case TARGET_SIGALRM:
1320                 case TARGET_SIGVTALRM:
1321                 case TARGET_SIGPROF:
1322                 case TARGET_SIGSTOP:
1323
1324                 case TARGET_SIGPIPE:
1325                 case TARGET_SIGLOST:
1326                 case TARGET_SIGXCPU:
1327                 case TARGET_SIGXFSZ:
1328                 case TARGET_SIGUSR1:
1329                 case TARGET_SIGUSR2:
1330                   sim_io_eprintf (CPU_STATE (current_cpu),
1331                                   "Exiting pid %d due to signal %d\n",
1332                                   pid, sig);
1333                   sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
1334                                    NULL, pc, sim_stopped,
1335                                    sig == TARGET_SIGABRT
1336                                    ? SIM_SIGABRT : SIM_SIGILL);
1337                   return 0;
1338
1339                   /* The default for all other signals is to be ignored.  */
1340                 default:
1341                   return 0;
1342                 }
1343
1344             case TARGET_SIG_IGN:
1345               switch (sig)
1346                 {
1347                 case TARGET_SIGKILL:
1348                 case TARGET_SIGSTOP:
1349                   /* Can't ignore these signals.  */
1350                   sim_io_eprintf (CPU_STATE (current_cpu),
1351                                   "Exiting pid %d due to signal %d\n",
1352                                   pid, sig);
1353                   sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
1354                                    NULL, pc, sim_stopped, SIM_SIGILL);
1355                   return 0;
1356
1357                 default:
1358                   return 0;
1359                 }
1360               break;
1361
1362             default:
1363               /* Mark the signal as pending, making schedule () check
1364                  closer.  The signal will be handled when the thread is
1365                  scheduled and the signal is unblocked.  */
1366               current_cpu->thread_data[i].sigdata[sig].pending = 1;
1367               current_cpu->thread_data[i].sigpending = 1;
1368               return 0;
1369             }
1370         else
1371           {
1372             sim_io_eprintf (CPU_STATE (current_cpu),
1373                             "Unimplemented signal: %d\n", sig);
1374             sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc,
1375                              sim_stopped, SIM_SIGILL);
1376           }
1377       }
1378
1379   return
1380     -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu)),
1381                               ESRCH);
1382 }
1383
1384 /* Make the vector and the first item, the main thread.  */
1385
1386 static void
1387 make_first_thread (SIM_CPU *current_cpu)
1388 {
1389   current_cpu->thread_data
1390     = xcalloc (1,
1391                SIM_TARGET_MAX_THREADS
1392                * sizeof (current_cpu->thread_data[0]));
1393   current_cpu->thread_data[0].cpu_context
1394     = (*current_cpu->make_thread_cpu_data) (current_cpu,
1395                                             &current_cpu
1396                                             ->cpu_data_placeholder);
1397   current_cpu->thread_data[0].parent_threadid = -1;
1398
1399   /* For good measure.  */
1400   if (TARGET_SIG_DFL != 0)
1401     abort ();
1402 }
1403
1404 /* Handle unknown system calls.  Returns (if it does) the syscall
1405    return value.  */
1406
1407 static USI
1408 cris_unknown_syscall (SIM_CPU *current_cpu, USI pc, char *s, ...)
1409 {
1410   SIM_DESC sd = CPU_STATE (current_cpu);
1411   host_callback *cb = STATE_CALLBACK (sd);
1412
1413   if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP
1414       || cris_unknown_syscall_action == CRIS_USYSC_MSG_ENOSYS)
1415     {
1416       va_list ap;
1417
1418       va_start (ap, s);
1419       sim_io_evprintf (sd, s, ap);
1420       va_end (ap);
1421
1422       if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP)
1423         sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
1424     }
1425
1426   return -cb_host_to_target_errno (cb, ENOSYS);
1427 }
1428
1429 /* Main function: the handler of the "break 13" syscall insn.  */
1430
1431 USI
1432 cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
1433                        USI arg2, USI arg3, USI arg4, USI arg5, USI arg6,
1434                        USI pc)
1435 {
1436   CB_SYSCALL s;
1437   SIM_DESC sd = CPU_STATE (current_cpu);
1438   host_callback *cb = STATE_CALLBACK (sd);
1439   int retval;
1440   int threadno = current_cpu->threadno;
1441
1442   current_cpu->syscalls++;
1443
1444   CB_SYSCALL_INIT (&s);
1445   s.func = callnum;
1446   s.arg1 = arg1;
1447   s.arg2 = arg2;
1448   s.arg3 = arg3;
1449
1450   if (callnum == TARGET_SYS_exit && current_cpu->m1threads == 0)
1451     {
1452       if (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
1453           & FLAG_CRIS_MISC_PROFILE_ALL)
1454         dump_statistics (current_cpu);
1455       sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, arg1);
1456     }
1457
1458   s.p1 = (PTR) sd;
1459   s.p2 = (PTR) current_cpu;
1460   s.read_mem = syscall_read_mem;
1461   s.write_mem = syscall_write_mem;
1462
1463   current_cpu_for_cb_callback = current_cpu;
1464
1465   if (cb_syscall (cb, &s) != CB_RC_OK)
1466     {
1467       abort ();
1468       sim_io_eprintf (sd, "Break 13: invalid %d?  Returned %ld\n", callnum,
1469                       s.result);
1470       sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
1471     }
1472
1473   retval = s.result == -1 ? -s.errcode : s.result;
1474
1475   if (s.errcode != 0 && s.errcode == cb_host_to_target_errno (cb, ENOSYS))
1476     {
1477       /* If the generic simulator call said ENOSYS, then let's try the
1478          ones we know ourselves.
1479
1480          The convention is to provide *very limited* functionality on an
1481          as-needed basis, only what's covered by the test-suite, tests
1482          added when functionality changes and abort with a descriptive
1483          message for *everything* else.  Where there's no test-case, we
1484          just abort.  */
1485       switch (callnum)
1486         {
1487         case 0:
1488           /* It's a pretty safe bet that the "old setup() system call"
1489              number will not be re-used; we can't say the same for higher
1490              numbers.  We treat this simulator-generated call as "wait
1491              forever"; we re-run this insn.  The wait is ended by a
1492              callback.  Sanity check that this is the reason we got
1493              here. */
1494           if (current_cpu->thread_data == NULL
1495               || (current_cpu->thread_data[threadno].pipe_write_fd == 0))
1496             goto unimplemented_syscall;
1497
1498           sim_pc_set (current_cpu, pc);
1499           retval = arg1;
1500           break;
1501
1502         case TARGET_SYS_fcntl64:
1503         case TARGET_SYS_fcntl:
1504           switch (arg2)
1505             {
1506             case 1:
1507               /* F_GETFD.
1508                  Glibc checks stdin, stdout and stderr fd:s for
1509                  close-on-exec security sanity.  We just need to provide a
1510                  OK return value.  If we really need to have a
1511                  close-on-exec flag true, we could just do a real fcntl
1512                  here.  */
1513               retval = 0;
1514               break;
1515
1516             case 2:
1517               /* F_SETFD.  Just ignore attempts to set the close-on-exec
1518                  flag.  */
1519               retval = 0;
1520               break;
1521
1522             case 3:
1523               /* F_GETFL.  Check for the special case for open+fdopen.  */
1524               if (current_cpu->last_syscall == TARGET_SYS_open
1525                   && arg1 == current_cpu->last_open_fd)
1526                 {
1527                   retval = current_cpu->last_open_flags & TARGET_O_ACCMODE;
1528                   break;
1529                 }
1530               else if (arg1 == 0)
1531                 {
1532                   /* Because we can't freopen fd:s 0, 1, 2 to mean
1533                      something else than stdin, stdout and stderr
1534                      (sim/common/syscall.c:cb_syscall special cases fd
1535                      0, 1 and 2), we know what flags that we can
1536                      sanely return for these fd:s.  */
1537                   retval = TARGET_O_RDONLY;
1538                   break;
1539                 }
1540               else if (arg1 == 1 || arg1 == 2)
1541                 {
1542                   retval = TARGET_O_WRONLY;
1543                   break;
1544                 }
1545               /* FALLTHROUGH */
1546             default:
1547               /* Nothing else is implemented.  */
1548               retval
1549                 = cris_unknown_syscall (current_cpu, pc,
1550                                         "Unimplemented %s syscall "
1551                                         "(fd: 0x%lx: cmd: 0x%lx arg: "
1552                                         "0x%lx)\n",
1553                                         callnum == TARGET_SYS_fcntl
1554                                         ? "fcntl" : "fcntl64",
1555                                         (unsigned long) (USI) arg1,
1556                                         (unsigned long) (USI) arg2,
1557                                         (unsigned long) (USI) arg3);
1558               break;
1559             }
1560           break;
1561
1562         case TARGET_SYS_uname:
1563           {
1564             /* Fill in a few constants to appease glibc.  */
1565             static const char sim_utsname[6][65] =
1566             {
1567               "Linux",
1568               "sim-target",
1569               "2.4.5",
1570               TARGET_UTSNAME,
1571               "cris",
1572               "localdomain"
1573             };
1574
1575             if ((s.write_mem) (cb, &s, arg1, (const char *) sim_utsname,
1576                                sizeof (sim_utsname))
1577                 != sizeof (sim_utsname))
1578               retval = -cb_host_to_target_errno (cb, EFAULT);
1579             else
1580               retval = 0;
1581             break;
1582           }
1583
1584         case TARGET_SYS_geteuid32:
1585           /* We tell the truth with these.  Maybe we shouldn't, but it
1586              should match the "stat" information.  */
1587           retval = geteuid ();
1588           break;
1589
1590         case TARGET_SYS_getuid32:
1591           retval = getuid ();
1592           break;
1593
1594         case TARGET_SYS_getegid32:
1595           retval = getegid ();
1596           break;
1597
1598         case TARGET_SYS_getgid32:
1599           retval = getgid ();
1600           break;
1601
1602         case TARGET_SYS_brk:
1603           /* Most often, we just return the argument, like the Linux
1604              kernel.  */
1605           retval = arg1;
1606
1607           if (arg1 == 0)
1608             retval = current_cpu->endbrk;
1609           else if (arg1 <= current_cpu->endmem)
1610             current_cpu->endbrk = arg1;
1611           else
1612             {
1613               USI new_end = (arg1 + 8191) & ~8191;
1614
1615               /* If the simulator wants to brk more than a certain very
1616                  large amount, something is wrong.  FIXME: Return an error
1617                  or abort?  Have command-line selectable?  */
1618               if (new_end - current_cpu->endmem > SIM_MAX_ALLOC_CHUNK)
1619                 {
1620                   current_cpu->endbrk = current_cpu->endmem;
1621                   retval = current_cpu->endmem;
1622                   break;
1623                 }
1624
1625               sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
1626                                current_cpu->endmem,
1627                                new_end - current_cpu->endmem,
1628                                0, NULL, NULL);
1629               current_cpu->endbrk = arg1;
1630               current_cpu->endmem = new_end;
1631             }
1632           break;
1633
1634         case TARGET_SYS_getpid:
1635           /* Correct until CLONE_THREAD is implemented.  */
1636           retval = current_cpu->thread_data == NULL
1637             ? TARGET_PID
1638             : TARGET_PID + current_cpu->thread_data[threadno].threadid;
1639           break;
1640
1641         case TARGET_SYS_getppid:
1642           /* Correct until CLONE_THREAD is implemented.  */
1643           retval = current_cpu->thread_data == NULL
1644             ? TARGET_PID - 1
1645             : (TARGET_PID
1646                + current_cpu->thread_data[threadno].parent_threadid);
1647           break;
1648
1649         case TARGET_SYS_mmap2:
1650           {
1651             USI addr = arg1;
1652             USI len = arg2;
1653             USI prot = arg3;
1654             USI flags = arg4;
1655             USI fd = arg5;
1656             USI pgoff = arg6;
1657
1658             /* If the simulator wants to mmap more than the very large
1659                limit, something is wrong.  FIXME: Return an error or
1660                abort?  Have command-line selectable?  */
1661             if (len > SIM_MAX_ALLOC_CHUNK)
1662               {
1663                 retval = -cb_host_to_target_errno (cb, ENOMEM);
1664                 break;
1665               }
1666
1667             if ((prot != (TARGET_PROT_READ | TARGET_PROT_WRITE)
1668                  && (prot
1669                      != (TARGET_PROT_READ
1670                          | TARGET_PROT_WRITE
1671                          | TARGET_PROT_EXEC))
1672                  && (prot != (TARGET_PROT_READ | TARGET_PROT_EXEC))
1673                  && prot != TARGET_PROT_READ)
1674                 || (flags != (TARGET_MAP_ANONYMOUS | TARGET_MAP_PRIVATE)
1675                     && flags != TARGET_MAP_PRIVATE
1676                     && flags != (TARGET_MAP_ANONYMOUS
1677                                  | TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
1678                     && flags != (TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
1679                     && flags != TARGET_MAP_SHARED)
1680                 || (fd != (USI) -1
1681                     && prot != TARGET_PROT_READ
1682                     && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
1683                     && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
1684                 || (fd == (USI) -1 && pgoff != 0)
1685                 || (fd != (USI) -1 && (flags & TARGET_MAP_ANONYMOUS))
1686                 || ((flags & TARGET_MAP_FIXED) == 0
1687                     && is_mapped (sd, &current_cpu->highest_mmapped_page,
1688                                   addr, (len + 8191) & ~8191)))
1689               {
1690                 retval
1691                   = cris_unknown_syscall (current_cpu, pc,
1692                                                  "Unimplemented mmap2 call "
1693                                                  "(0x%lx, 0x%lx, 0x%lx, "
1694                                                  "0x%lx, 0x%lx, 0x%lx)\n",
1695                                                  (unsigned long) arg1,
1696                                                  (unsigned long) arg2,
1697                                                  (unsigned long) arg3,
1698                                                  (unsigned long) arg4,
1699                                                  (unsigned long) arg5,
1700                                                  (unsigned long) arg6);
1701                 break;
1702               }
1703             else if (fd != (USI) -1)
1704               {
1705                 /* Map a file.  */
1706
1707                 USI newaddr;
1708                 USI pos;
1709
1710                 /* A non-aligned argument is allowed for files.  */
1711                 USI newlen = (len + 8191) & ~8191;
1712
1713                 /* We only support read, read|exec, and read|write,
1714                    which we should already have checked.  Check again
1715                    anyway.  */
1716                 if (prot != TARGET_PROT_READ
1717                     && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
1718                     && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
1719                   abort ();
1720
1721                 if ((flags & TARGET_MAP_FIXED)
1722                     && unmap_pages (sd, &current_cpu->highest_mmapped_page,
1723                                     addr, newlen) != 0)
1724                   abort ();
1725
1726                 newaddr
1727                   = create_map (sd, &current_cpu->highest_mmapped_page, addr,
1728                                 newlen);
1729
1730                 if (newaddr >= (USI) -8191)
1731                   {
1732                     abort ();
1733                     retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
1734                     break;
1735                   }
1736
1737                 /* We were asked for MAP_FIXED, but couldn't.  */
1738                 if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
1739                   {
1740                     abort ();
1741                     unmap_pages (sd, &current_cpu->highest_mmapped_page,
1742                                  newaddr, newlen);
1743                     retval = -cb_host_to_target_errno (cb, EINVAL);
1744                     break;
1745                   }
1746
1747                 /* Find the current position in the file.  */
1748                 s.func = TARGET_SYS_lseek;
1749                 s.arg1 = fd;
1750                 s.arg2 = 0;
1751                 s.arg3 = SEEK_CUR;
1752                 if (cb_syscall (cb, &s) != CB_RC_OK)
1753                   abort ();
1754                 pos = s.result;
1755
1756                 if (s.result < 0)
1757                   abort ();
1758
1759                 /* Move to the correct offset in the file.  */
1760                 s.func = TARGET_SYS_lseek;
1761                 s.arg1 = fd;
1762                 s.arg2 = pgoff*8192;
1763                 s.arg3 = SEEK_SET;
1764                 if (cb_syscall (cb, &s) != CB_RC_OK)
1765                   abort ();
1766
1767                 if (s.result < 0)
1768                   abort ();
1769
1770                 /* Use the standard read callback to read in "len"
1771                    bytes.  */
1772                 s.func = TARGET_SYS_read;
1773                 s.arg1 = fd;
1774                 s.arg2 = newaddr;
1775                 s.arg3 = len;
1776                 if (cb_syscall (cb, &s) != CB_RC_OK)
1777                   abort ();
1778
1779                 if ((USI) s.result != len)
1780                   abort ();
1781
1782                 /* After reading, we need to go back to the previous
1783                    position in the file.  */
1784                 s.func = TARGET_SYS_lseek;
1785                 s.arg1 = fd;
1786                 s.arg2 = pos;
1787                 s.arg3 = SEEK_SET;
1788                 if (cb_syscall (cb, &s) != CB_RC_OK)
1789                   abort ();
1790                 if (pos != (USI) s.result)
1791                   abort ();
1792
1793                 retval = newaddr;
1794               }
1795             else
1796               {
1797                 USI newlen = (len + 8191) & ~8191;
1798                 USI newaddr;
1799
1800                 if ((flags & TARGET_MAP_FIXED)
1801                     && unmap_pages (sd, &current_cpu->highest_mmapped_page,
1802                                     addr, newlen) != 0)
1803                   abort ();
1804
1805                 newaddr = create_map (sd, &current_cpu->highest_mmapped_page, addr,
1806                                 newlen);
1807
1808                 if (newaddr >= (USI) -8191)
1809                   retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
1810                 else
1811                   retval = newaddr;
1812
1813                 if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
1814                   {
1815                     abort ();
1816                     unmap_pages (sd, &current_cpu->highest_mmapped_page,
1817                                  newaddr, newlen);
1818                     retval = -cb_host_to_target_errno (cb, EINVAL);
1819                     break;
1820                   }
1821               }
1822             break;
1823           }
1824
1825         case TARGET_SYS_mprotect:
1826           {
1827             /* We only cover the case of linuxthreads mprotecting out
1828                its stack guard page and of dynamic loading mprotecting
1829                away the data (for some reason the whole library, then
1830                mprotects away the data part and mmap-FIX:es it again.  */
1831             USI addr = arg1;
1832             USI len = arg2;
1833             USI prot = arg3;
1834
1835             if (prot != TARGET_PROT_NONE
1836                 || !is_mapped_only (sd, &current_cpu->highest_mmapped_page,
1837                                     addr, (len + 8191) & ~8191))
1838               {
1839                 retval
1840                   = cris_unknown_syscall (current_cpu, pc,
1841                                           "Unimplemented mprotect call "
1842                                           "(0x%lx, 0x%lx, 0x%lx)\n",
1843                                           (unsigned long) arg1,
1844                                           (unsigned long) arg2,
1845                                           (unsigned long) arg3);
1846                 break;
1847               }
1848
1849             /* Just ignore this.  We could make this equal to munmap,
1850                but then we'd have to make sure no anon mmaps gets this
1851                address before a subsequent MAP_FIXED mmap intended to
1852                override it.  */
1853             retval = 0;
1854             break;
1855           }
1856
1857         case TARGET_SYS_ioctl:
1858           {
1859             /* We support only a very limited functionality: checking
1860                stdout with TCGETS to perform the isatty function.  The
1861                TCGETS ioctl isn't actually performed or the result used by
1862                an isatty () caller in a "hello, world" program; only the
1863                return value is then used.  Maybe we shouldn't care about
1864                the environment of the simulator regarding isatty, but
1865                that's been working before, in the xsim simulator.  */
1866             if (arg2 == TARGET_TCGETS && arg1 == 1)
1867               retval = isatty (1) ? 0 : cb_host_to_target_errno (cb, EINVAL);
1868             else
1869               retval = -cb_host_to_target_errno (cb, EINVAL);
1870             break;
1871           }
1872
1873         case TARGET_SYS_munmap:
1874           {
1875             USI addr = arg1;
1876             USI len = arg2;
1877             USI result
1878               = unmap_pages (sd, &current_cpu->highest_mmapped_page, addr,
1879                              len);
1880             retval = result != 0 ? -cb_host_to_target_errno (cb, result) : 0;
1881             break;
1882           }
1883
1884         case TARGET_SYS_wait4:
1885           {
1886             int i;
1887             USI pid = arg1;
1888             USI saddr = arg2;
1889             USI options = arg3;
1890             USI rusagep = arg4;
1891
1892             /* FIXME: We're not properly implementing __WCLONE, and we
1893                don't really need the special casing so we might as well
1894                make this general.  */
1895             if ((!(pid == (USI) -1
1896                    && options == (TARGET___WCLONE | TARGET_WNOHANG)
1897                    && saddr != 0)
1898                  && !(pid > 0
1899                       && (options == TARGET___WCLONE
1900                           || options == TARGET___WALL)))
1901                 || rusagep != 0
1902                 || current_cpu->thread_data == NULL)
1903               {
1904                 retval
1905                   = cris_unknown_syscall (current_cpu, pc,
1906                                           "Unimplemented wait4 call "
1907                                           "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1908                                           (unsigned long) arg1,
1909                                           (unsigned long) arg2,
1910                                           (unsigned long) arg3,
1911                                           (unsigned long) arg4);
1912                 break;
1913               }
1914
1915             if (pid == (USI) -1)
1916               for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
1917                 {
1918                   if (current_cpu->thread_data[threadno].threadid
1919                       == current_cpu->thread_data[i].parent_threadid
1920                       && current_cpu->thread_data[i].threadid != 0
1921                       && current_cpu->thread_data[i].cpu_context == NULL)
1922                     {
1923                       /* A zombied child.  Get the exit value and clear the
1924                          zombied entry so it will be reused.  */
1925                       sim_core_write_unaligned_4 (current_cpu, pc, 0, saddr,
1926                                                   current_cpu
1927                                                   ->thread_data[i].exitval);
1928                       retval
1929                         = current_cpu->thread_data[i].threadid + TARGET_PID;
1930                       memset (&current_cpu->thread_data[i], 0,
1931                               sizeof (current_cpu->thread_data[i]));
1932                       goto outer_break;
1933                     }
1934                 }
1935             else
1936               {
1937                 /* We're waiting for a specific PID.  If we don't find
1938                    it zombied on this run, rerun the syscall.  */
1939                 for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
1940                   if (pid == current_cpu->thread_data[i].threadid + TARGET_PID
1941                       && current_cpu->thread_data[i].cpu_context == NULL)
1942                     {
1943                       if (saddr != 0)
1944                         /* Get the exit value if the caller wants it.  */
1945                         sim_core_write_unaligned_4 (current_cpu, pc, 0,
1946                                                     saddr,
1947                                                     current_cpu
1948                                                     ->thread_data[i]
1949                                                     .exitval);
1950
1951                       retval
1952                         = current_cpu->thread_data[i].threadid + TARGET_PID;
1953                       memset (&current_cpu->thread_data[i], 0,
1954                               sizeof (current_cpu->thread_data[i]));
1955
1956                       goto outer_break;
1957                     }
1958
1959                 sim_pc_set (current_cpu, pc);
1960               }
1961
1962             retval = -cb_host_to_target_errno (cb, ECHILD);
1963           outer_break:
1964             break;
1965           }
1966
1967         case TARGET_SYS_rt_sigaction:
1968           {
1969             USI signum = arg1;
1970             USI old_sa = arg3;
1971             USI new_sa = arg2;
1972
1973             /* The kernel says:
1974                struct sigaction {
1975                         __sighandler_t sa_handler;
1976                         unsigned long sa_flags;
1977                         void (*sa_restorer)(void);
1978                         sigset_t sa_mask;
1979                }; */
1980
1981             if (old_sa != 0)
1982               {
1983                 sim_core_write_unaligned_4 (current_cpu, pc, 0, old_sa + 0,
1984                                             current_cpu->sighandler[signum]);
1985                 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 4, 0);
1986                 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 8, 0);
1987
1988                 /* We'll assume _NSIG_WORDS is 2 for the kernel.  */
1989                 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 12, 0);
1990                 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 16, 0);
1991               }
1992             if (new_sa != 0)
1993               {
1994                 USI target_sa_handler
1995                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa);
1996                 USI target_sa_flags
1997                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 4);
1998                 USI target_sa_restorer
1999                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 8);
2000                 USI target_sa_mask_low
2001                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 12);
2002                 USI target_sa_mask_high
2003                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 16);
2004
2005                 /* We won't interrupt a syscall so we won't restart it,
2006                    but a signal(2) call ends up syscalling rt_sigaction
2007                    with this flag, so we have to handle it.  The
2008                    sa_restorer field contains garbage when not
2009                    TARGET_SA_RESTORER, so don't look at it.  For the
2010                    time being, we don't nest sighandlers, so we
2011                    ignore the sa_mask, which simplifies things.  */
2012                 if ((target_sa_flags != 0
2013                      && target_sa_flags != TARGET_SA_RESTART
2014                      && target_sa_flags != (TARGET_SA_RESTART|TARGET_SA_SIGINFO))
2015                     || target_sa_handler == 0)
2016                   {
2017                     retval
2018                       = cris_unknown_syscall (current_cpu, pc,
2019                                               "Unimplemented rt_sigaction "
2020                                               "syscall "
2021                                               "(0x%lx, 0x%lx: "
2022                                               "[0x%x, 0x%x, 0x%x, "
2023                                               "{0x%x, 0x%x}], 0x%lx)\n",
2024                                               (unsigned long) arg1,
2025                                               (unsigned long) arg2,
2026                                               target_sa_handler,
2027                                               target_sa_flags,
2028                                               target_sa_restorer,
2029                                               target_sa_mask_low,
2030                                               target_sa_mask_high,
2031                                               (unsigned long) arg3);
2032                     break;
2033                   }
2034
2035                 current_cpu->sighandler[signum] = target_sa_handler;
2036
2037                 /* Because we may have unblocked signals, one may now be
2038                    pending, if there are threads, that is.  */
2039                 if (current_cpu->thread_data)
2040                   current_cpu->thread_data[threadno].sigpending = 1;
2041               }
2042             retval = 0;
2043             break;
2044           }
2045
2046         case TARGET_SYS_mremap:
2047           {
2048             USI addr = arg1;
2049             USI old_len = arg2;
2050             USI new_len = arg3;
2051             USI flags = arg4;
2052             USI new_addr = arg5;
2053             USI mapped_addr;
2054
2055             if (new_len == old_len)
2056               /* The program and/or library is possibly confused but
2057                  this is a valid call.  Happens with ipps-1.40 on file
2058                  svs_all.  */
2059               retval = addr;
2060             else if (new_len < old_len)
2061               {
2062                 /* Shrinking is easy.  */
2063                 if (unmap_pages (sd, &current_cpu->highest_mmapped_page,
2064                                  addr + new_len, old_len - new_len) != 0)
2065                   retval = -cb_host_to_target_errno (cb, EINVAL);
2066                 else
2067                   retval = addr;
2068               }
2069             else if (! is_mapped (sd, &current_cpu->highest_mmapped_page,
2070                                   addr + old_len, new_len - old_len))
2071               {
2072                 /* If the extension isn't mapped, we can just add it.  */
2073                 mapped_addr
2074                   = create_map (sd, &current_cpu->highest_mmapped_page,
2075                                 addr + old_len, new_len - old_len);
2076
2077                 if (mapped_addr > (USI) -8192)
2078                   retval = -cb_host_to_target_errno (cb, -(SI) mapped_addr);
2079                 else
2080                   retval = addr;
2081               }
2082             else if (flags & TARGET_MREMAP_MAYMOVE)
2083               {
2084                 /* Create a whole new map and copy the contents
2085                    block-by-block there.  We ignore the new_addr argument
2086                    for now.  */
2087                 char buf[8192];
2088                 USI prev_addr = addr;
2089                 USI prev_len = old_len;
2090
2091                 mapped_addr
2092                   = create_map (sd, &current_cpu->highest_mmapped_page,
2093                                 0, new_len);
2094
2095                 if (mapped_addr > (USI) -8192)
2096                   {
2097                     retval = -cb_host_to_target_errno (cb, -(SI) new_addr);
2098                     break;
2099                   }
2100
2101                 retval = mapped_addr;
2102
2103                 for (; old_len > 0;
2104                      old_len -= 8192, mapped_addr += 8192, addr += 8192)
2105                   {
2106                     if (sim_core_read_buffer (sd, current_cpu, read_map, buf,
2107                                               addr, 8192) != 8192
2108                         || sim_core_write_buffer (sd, current_cpu, 0, buf,
2109                                                   mapped_addr, 8192) != 8192)
2110                       abort ();
2111                   }
2112
2113                 if (unmap_pages (sd, &current_cpu->highest_mmapped_page,
2114                                  prev_addr, prev_len) != 0)
2115                   abort ();
2116               }
2117             else
2118               retval = -cb_host_to_target_errno (cb, -ENOMEM);
2119             break;
2120           }
2121
2122         case TARGET_SYS_poll:
2123           {
2124             int npollfds = arg2;
2125             int timeout = arg3;
2126             SI ufds = arg1;
2127             SI fd = -1;
2128             HI events = -1;
2129             HI revents = 0;
2130             struct stat buf;
2131             int i;
2132
2133             /* The kernel says:
2134                 struct pollfd {
2135                      int fd;
2136                      short events;
2137                      short revents;
2138                 }; */
2139
2140             /* Check that this is the expected poll call from
2141                linuxthreads/manager.c; we don't support anything else.
2142                Remember, fd == 0 isn't supported.  */
2143             if (npollfds != 1
2144                 || ((fd = sim_core_read_unaligned_4 (current_cpu, pc,
2145                                                      0, ufds)) <= 0)
2146                 || ((events = sim_core_read_unaligned_2 (current_cpu, pc,
2147                                                          0, ufds + 4))
2148                     != TARGET_POLLIN)
2149                 || ((cb->fstat) (cb, fd, &buf) != 0
2150                     || (buf.st_mode & S_IFIFO) == 0)
2151                 || current_cpu->thread_data == NULL)
2152               {
2153                 retval
2154                   = cris_unknown_syscall (current_cpu, pc,
2155                                           "Unimplemented poll syscall "
2156                                           "(0x%lx: [0x%x, 0x%x, x], "
2157                                           "0x%lx, 0x%lx)\n",
2158                                           (unsigned long) arg1, fd, events,
2159                                           (unsigned long) arg2,
2160                                           (unsigned long) arg3);
2161                 break;
2162               }
2163
2164             retval = 0;
2165
2166             /* Iterate over threads; find a marker that a writer is
2167                sleeping, waiting for a reader.  */
2168             for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
2169               if (current_cpu->thread_data[i].cpu_context != NULL
2170                   && current_cpu->thread_data[i].pipe_read_fd == fd)
2171                 {
2172                   revents = TARGET_POLLIN;
2173                   retval = 1;
2174                   break;
2175                 }
2176
2177             /* Timeout decreases with whatever time passed between the
2178                last syscall and this.  That's not exactly right for the
2179                first call, but it's close enough that it isn't
2180                worthwhile to complicate matters by making that a special
2181                case.  */
2182             timeout
2183               -= (TARGET_TIME_MS (current_cpu)
2184                   - (current_cpu->thread_data[threadno].last_execution));
2185
2186             /* Arrange to repeat this syscall until timeout or event,
2187                decreasing timeout at each iteration.  */
2188             if (timeout > 0 && revents == 0)
2189               {
2190                 bfd_byte timeout_buf[4];
2191
2192                 bfd_putl32 (timeout, timeout_buf);
2193                 (*CPU_REG_STORE (current_cpu)) (current_cpu,
2194                                                 H_GR_R12, timeout_buf, 4);
2195                 sim_pc_set (current_cpu, pc);
2196                 retval = arg1;
2197                 break;
2198               }
2199
2200             sim_core_write_unaligned_2 (current_cpu, pc, 0, ufds + 4 + 2,
2201                                         revents);
2202             break;
2203           }
2204
2205         case TARGET_SYS_time:
2206           {
2207             retval = (int) (*cb->time) (cb, 0L);
2208
2209             /* At time of this writing, CB_SYSCALL_time doesn't do the
2210                part of setting *arg1 to the return value.  */
2211             if (arg1)
2212               sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, retval);
2213             break;
2214           }
2215
2216         case TARGET_SYS_gettimeofday:
2217           if (arg1 != 0)
2218             {
2219               USI ts = TARGET_TIME (current_cpu);
2220               USI tms = TARGET_TIME_MS (current_cpu);
2221
2222               /* First dword is seconds since TARGET_EPOCH.  */
2223               sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, ts);
2224
2225               /* Second dword is microseconds.  */
2226               sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1 + 4,
2227                                           (tms % 1000) * 1000);
2228             }
2229           if (arg2 != 0)
2230             {
2231               /* Time-zone info is always cleared.  */
2232               sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, 0);
2233               sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, 0);
2234             }
2235           retval = 0;
2236           break;
2237
2238         case TARGET_SYS_llseek:
2239           {
2240             /* If it fits, tweak parameters to fit the "generic" 32-bit
2241                lseek and use that.  */
2242             SI fd = arg1;
2243             SI offs_hi = arg2;
2244             SI offs_lo = arg3;
2245             SI resultp = arg4;
2246             SI whence = arg5;
2247             retval = 0;
2248
2249             if (!((offs_hi == 0 && offs_lo >= 0)
2250                   || (offs_hi == -1 &&  offs_lo < 0)))
2251               {
2252                 retval
2253                   = cris_unknown_syscall (current_cpu, pc,
2254                                           "Unimplemented llseek offset,"
2255                                           " fd %d: 0x%x:0x%x\n",
2256                                           fd, (unsigned) arg2,
2257                                           (unsigned) arg3);
2258                 break;
2259               }
2260
2261             s.func = TARGET_SYS_lseek;
2262             s.arg2 = offs_lo;
2263             s.arg3 = whence;
2264             if (cb_syscall (cb, &s) != CB_RC_OK)
2265               {
2266                 sim_io_eprintf (sd, "Break 13: invalid %d?  Returned %ld\n", callnum,
2267                                 s.result);
2268                 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
2269               }
2270             if (s.result < 0)
2271               retval = -s.errcode;
2272             else
2273               {
2274                 sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp,
2275                                             s.result);
2276                 sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp + 4,
2277                                             s.result < 0 ? -1 : 0);
2278               }
2279             break;
2280           }
2281
2282           /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2283               where:
2284              struct iovec {
2285                void  *iov_base;    Starting address
2286                size_t iov_len;     Number of bytes to transfer
2287              }; */
2288         case TARGET_SYS_writev:
2289           {
2290             SI fd = arg1;
2291             SI iov = arg2;
2292             SI iovcnt = arg3;
2293             SI retcnt = 0;
2294             int i;
2295
2296             /* We'll ignore strict error-handling and just do multiple write calls.  */
2297             for (i = 0; i < iovcnt; i++)
2298               {
2299                 int sysret;
2300                 USI iov_base
2301                   = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2302                                                iov + 8*i);
2303                 USI iov_len
2304                   = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2305                                                iov + 8*i + 4);
2306                 
2307                 s.func = TARGET_SYS_write;
2308                 s.arg1 = fd;
2309                 s.arg2 = iov_base;
2310                 s.arg3 = iov_len;
2311
2312                 if (cb_syscall (cb, &s) != CB_RC_OK)
2313                   abort ();
2314                 sysret = s.result == -1 ? -s.errcode : s.result;
2315
2316                 if (sysret != iov_len)
2317                   {
2318                     if (i != 0)
2319                       abort ();
2320                     retcnt = sysret;
2321                     break;
2322                   }
2323
2324                 retcnt += iov_len;
2325               }
2326
2327             retval = retcnt;
2328           }
2329           break;
2330
2331         /* This one does have a generic callback function, but at the time
2332            of this writing, cb_syscall does not have code for it, and we
2333            need target-specific code for the threads implementation
2334            anyway.  */
2335         case TARGET_SYS_kill:
2336           {
2337             USI pid = arg1;
2338             USI sig = arg2;
2339
2340             retval = 0;
2341
2342             /* At kill(2), glibc sets signal masks such that the thread
2343                machinery is initialized.  Still, there is and was only
2344                one thread.  */
2345             if (current_cpu->max_threadid == 0)
2346               {
2347                 if (pid != TARGET_PID)
2348                   {
2349                     retval = -cb_host_to_target_errno (cb, EPERM);
2350                     break;
2351                   }
2352
2353                 /* FIXME: Signal infrastructure (target-to-sim mapping).  */
2354                 if (sig == TARGET_SIGABRT)
2355                   /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2356                      the end-point for failing GCC test-cases.  */
2357                   sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2358                                    SIM_SIGABRT);
2359                 else
2360                   {
2361                     sim_io_eprintf (sd, "Unimplemented signal: %d\n", sig);
2362                     sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2363                                      SIM_SIGILL);
2364                   }
2365
2366                 /* This will not be reached.  */
2367                 abort ();
2368               }
2369             else
2370               retval = deliver_signal (current_cpu, sig, pid);
2371             break;
2372           }
2373
2374         case TARGET_SYS_rt_sigprocmask:
2375           {
2376             int i;
2377             USI how = arg1;
2378             USI newsetp = arg2;
2379             USI oldsetp = arg3;
2380
2381             if (how != TARGET_SIG_BLOCK
2382                 && how != TARGET_SIG_SETMASK
2383                 && how != TARGET_SIG_UNBLOCK)
2384               {
2385                 retval
2386                   = cris_unknown_syscall (current_cpu, pc,
2387                                           "Unimplemented rt_sigprocmask "
2388                                           "syscall (0x%x, 0x%x, 0x%x)\n",
2389                                           arg1, arg2, arg3);
2390                 break;
2391               }
2392
2393             if (newsetp)
2394               {
2395                 USI set_low
2396                   = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2397                                                newsetp);
2398                 USI set_high
2399                   = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2400                                                newsetp + 4);
2401
2402                 /* The sigmask is kept in the per-thread data, so we may
2403                    need to create the first one.  */
2404                 if (current_cpu->thread_data == NULL)
2405                   make_first_thread (current_cpu);
2406
2407                 if (how == TARGET_SIG_SETMASK)
2408                   for (i = 0; i < 64; i++)
2409                     current_cpu->thread_data[threadno].sigdata[i].blocked = 0;
2410
2411                 for (i = 0; i < 32; i++)
2412                   if ((set_low & (1 << i)))
2413                     current_cpu->thread_data[threadno].sigdata[i + 1].blocked
2414                       = (how != TARGET_SIG_UNBLOCK);
2415
2416                 for (i = 0; i < 31; i++)
2417                   if ((set_high & (1 << i)))
2418                     current_cpu->thread_data[threadno].sigdata[i + 33].blocked
2419                       = (how != TARGET_SIG_UNBLOCK);
2420
2421                 /* The mask changed, so a signal may be unblocked for
2422                    execution.  */
2423                 current_cpu->thread_data[threadno].sigpending = 1;
2424               }
2425
2426             if (oldsetp != 0)
2427               {
2428                 USI set_low = 0;
2429                 USI set_high = 0;
2430
2431                 for (i = 0; i < 32; i++)
2432                   if (current_cpu->thread_data[threadno]
2433                       .sigdata[i + 1].blocked)
2434                     set_low |= 1 << i;
2435                 for (i = 0; i < 31; i++)
2436                   if (current_cpu->thread_data[threadno]
2437                       .sigdata[i + 33].blocked)
2438                     set_high |= 1 << i;
2439
2440                 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 0, set_low);
2441                 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 4, set_high);
2442               }
2443
2444             retval = 0;
2445             break;
2446           }
2447
2448         case TARGET_SYS_sigreturn:
2449           {
2450             int i;
2451             bfd_byte regbuf[4];
2452             int was_sigsuspended;
2453
2454             if (current_cpu->thread_data == NULL
2455                 /* The CPU context is saved with the simulator data, not
2456                    on the stack as in the real world.  */
2457                 || (current_cpu->thread_data[threadno].cpu_context_atsignal
2458                     == NULL))
2459               {
2460                 retval
2461                   = cris_unknown_syscall (current_cpu, pc,
2462                                           "Invalid sigreturn syscall: "
2463                                           "no signal handler active "
2464                                           "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2465                                           "0x%lx, 0x%lx)\n",
2466                                           (unsigned long) arg1,
2467                                           (unsigned long) arg2,
2468                                           (unsigned long) arg3,
2469                                           (unsigned long) arg4,
2470                                           (unsigned long) arg5,
2471                                           (unsigned long) arg6);
2472                 break;
2473               }
2474
2475             was_sigsuspended
2476               = current_cpu->thread_data[threadno].sigsuspended;
2477
2478             /* Restore the sigmask, either from the stack copy made when
2479                the sighandler was called, or from the saved state
2480                specifically for sigsuspend(2).  */
2481             if (was_sigsuspended)
2482               {
2483                 current_cpu->thread_data[threadno].sigsuspended = 0;
2484                 for (i = 0; i < 64; i++)
2485                   current_cpu->thread_data[threadno].sigdata[i].blocked
2486                     = current_cpu->thread_data[threadno]
2487                     .sigdata[i].blocked_suspendsave;
2488               }
2489             else
2490               {
2491                 USI sp;
2492                 USI set_low;
2493                 USI set_high;
2494
2495                 (*CPU_REG_FETCH (current_cpu)) (current_cpu,
2496                                             H_GR_SP, regbuf, 4);
2497                 sp = bfd_getl32 (regbuf);
2498                 set_low
2499                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp);
2500                 set_high
2501                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp + 4);
2502
2503                 for (i = 0; i < 32; i++)
2504                   current_cpu->thread_data[threadno].sigdata[i + 1].blocked
2505                     = (set_low & (1 << i)) != 0;
2506                 for (i = 0; i < 31; i++)
2507                   current_cpu->thread_data[threadno].sigdata[i + 33].blocked
2508                     = (set_high & (1 << i)) != 0;
2509               }
2510
2511             /* The mask changed, so a signal may be unblocked for
2512                execution.  */
2513             current_cpu->thread_data[threadno].sigpending = 1;
2514
2515             memcpy (&current_cpu->cpu_data_placeholder,
2516                     current_cpu->thread_data[threadno].cpu_context_atsignal,
2517                     current_cpu->thread_cpu_data_size);
2518             free (current_cpu->thread_data[threadno].cpu_context_atsignal);
2519             current_cpu->thread_data[threadno].cpu_context_atsignal = NULL;
2520
2521             /* The return value must come from the saved R10.  */
2522             (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, regbuf, 4);
2523             retval = bfd_getl32 (regbuf);
2524
2525             /* We must also break the "sigsuspension loop".  */
2526             if (was_sigsuspended)
2527               sim_pc_set (current_cpu, sim_pc_get (current_cpu) + 2);
2528             break;
2529           }
2530
2531         case TARGET_SYS_rt_sigsuspend:
2532           {
2533             USI newsetp = arg1;
2534             USI setsize = arg2;
2535
2536             if (setsize != 8)
2537               {
2538                 retval
2539                   = cris_unknown_syscall (current_cpu, pc,
2540                                           "Unimplemented rt_sigsuspend syscall"
2541                                           " arguments (0x%lx, 0x%lx)\n",
2542                                           (unsigned long) arg1,
2543                                           (unsigned long) arg2);
2544                 break;
2545               }
2546
2547             /* Don't change the signal mask if we're already in
2548                sigsuspend state (i.e. this syscall is a rerun).  */
2549             else if (!current_cpu->thread_data[threadno].sigsuspended)
2550               {
2551                 USI set_low
2552                   = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2553                                                newsetp);
2554                 USI set_high
2555                   = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2556                                                newsetp + 4);
2557                 int i;
2558
2559                 /* Save the current sigmask and insert the user-supplied
2560                    one.  */
2561                 for (i = 0; i < 32; i++)
2562                   {
2563                     current_cpu->thread_data[threadno]
2564                       .sigdata[i + 1].blocked_suspendsave
2565                       = current_cpu->thread_data[threadno]
2566                       .sigdata[i + 1].blocked;
2567
2568                     current_cpu->thread_data[threadno]
2569                       .sigdata[i + 1].blocked = (set_low & (1 << i)) != 0;
2570                   }
2571                 for (i = 0; i < 31; i++)
2572                   {
2573                     current_cpu->thread_data[threadno]
2574                       .sigdata[i + 33].blocked_suspendsave
2575                       = current_cpu->thread_data[threadno]
2576                       .sigdata[i + 33].blocked;
2577                     current_cpu->thread_data[threadno]
2578                       .sigdata[i + 33].blocked = (set_high & (1 << i)) != 0;
2579                   }
2580
2581                 current_cpu->thread_data[threadno].sigsuspended = 1;
2582
2583                 /* The mask changed, so a signal may be unblocked for
2584                    execution. */
2585                 current_cpu->thread_data[threadno].sigpending = 1;
2586               }
2587
2588             /* Because we don't use arg1 (newsetp) when this syscall is
2589                rerun, it doesn't matter that we overwrite it with the
2590                (constant) return value.  */
2591             retval = -cb_host_to_target_errno (cb, EINTR);
2592             sim_pc_set (current_cpu, pc);
2593             break;
2594           }
2595
2596           /* Add case labels here for other syscalls using the 32-bit
2597              "struct stat", provided they have a corresponding simulator
2598              function of course.  */
2599         case TARGET_SYS_stat:
2600         case TARGET_SYS_fstat:
2601           {
2602             /* As long as the infrastructure doesn't cache anything
2603                related to the stat mapping, this trick gets us a dual
2604                "struct stat"-type mapping in the least error-prone way.  */
2605             const char *saved_map = cb->stat_map;
2606             CB_TARGET_DEFS_MAP *saved_syscall_map = cb->syscall_map;
2607
2608             cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_stat32_map;
2609             cb->stat_map = stat32_map;
2610
2611             if (cb_syscall (cb, &s) != CB_RC_OK)
2612               {
2613                 abort ();
2614                 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2615                                  SIM_SIGILL);
2616               }
2617             retval = s.result == -1 ? -s.errcode : s.result;
2618
2619             cb->stat_map = saved_map;
2620             cb->syscall_map = saved_syscall_map;
2621             break;
2622           }
2623
2624         case TARGET_SYS_getcwd:
2625           {
2626             USI buf = arg1;
2627             USI size = arg2;
2628
2629             char *cwd = xmalloc (SIM_PATHMAX);
2630             if (cwd != getcwd (cwd, SIM_PATHMAX))
2631               abort ();
2632
2633             /* FIXME: When and if we support chdir, we need something
2634                a bit more elaborate.  */
2635             if (simulator_sysroot[0] != '\0')
2636               strcpy (cwd, "/");
2637
2638             retval = -cb_host_to_target_errno (cb, ERANGE);
2639             if (strlen (cwd) + 1 <= size)
2640               {
2641                 retval = strlen (cwd) + 1;
2642                 if (sim_core_write_buffer (sd, current_cpu, 0, cwd,
2643                                            buf, retval)
2644                     != (unsigned int) retval)
2645                   retval = -cb_host_to_target_errno (cb, EFAULT);
2646               }
2647             free (cwd);
2648             break;
2649           }
2650
2651         case TARGET_SYS_readlink:
2652           {
2653             SI path = arg1;
2654             SI buf = arg2;
2655             SI bufsiz = arg3;
2656             char *pbuf = xmalloc (SIM_PATHMAX);
2657             char *lbuf = xmalloc (SIM_PATHMAX);
2658             char *lbuf_alloc = lbuf;
2659             int nchars = -1;
2660             int i;
2661             int o = 0;
2662
2663             if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/')
2664               {
2665                 strcpy (pbuf, simulator_sysroot);
2666                 o += strlen (simulator_sysroot);
2667               }
2668
2669             for (i = 0; i + o < SIM_PATHMAX; i++)
2670               {
2671                 pbuf[i + o]
2672                   = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i);
2673                 if (pbuf[i + o] == 0)
2674                   break;
2675               }
2676
2677             if (i + o == SIM_PATHMAX)
2678               {
2679                 retval = -cb_host_to_target_errno (cb, ENAMETOOLONG);
2680                 break;
2681               }
2682
2683             /* Intervene calls for certain files expected in the target
2684                proc file system.  */
2685             if (strcmp (pbuf + strlen (simulator_sysroot),
2686                         "/proc/" XSTRING (TARGET_PID) "/exe") == 0)
2687               {
2688                 char *argv0
2689                   = (STATE_PROG_ARGV (sd) != NULL
2690                      ? *STATE_PROG_ARGV (sd) : NULL);
2691
2692                 if (argv0 == NULL || *argv0 == '.')
2693                   {
2694                     retval
2695                       = cris_unknown_syscall (current_cpu, pc,
2696                                               "Unimplemented readlink syscall "
2697                                               "(0x%lx: [\"%s\"], 0x%lx)\n",
2698                                               (unsigned long) arg1, pbuf,
2699                                               (unsigned long) arg2);
2700                     break;
2701                   }
2702                 else if (*argv0 == '/')
2703                   {
2704                     if (strncmp (simulator_sysroot, argv0,
2705                                  strlen (simulator_sysroot)) == 0)
2706                       argv0 += strlen (simulator_sysroot);
2707
2708                     strcpy (lbuf, argv0);
2709                     nchars = strlen (argv0) + 1;
2710                   }
2711                 else
2712                   {
2713                     if (getcwd (lbuf, SIM_PATHMAX) != NULL
2714                         && strlen (lbuf) + 2 + strlen (argv0) < SIM_PATHMAX)
2715                       {
2716                         if (strncmp (simulator_sysroot, lbuf,
2717                                      strlen (simulator_sysroot)) == 0)
2718                           lbuf += strlen (simulator_sysroot);
2719
2720                         strcat (lbuf, "/");
2721                         strcat (lbuf, argv0);
2722                         nchars = strlen (lbuf) + 1;
2723                       }
2724                     else
2725                       abort ();
2726                   }
2727               }
2728             else
2729               nchars = readlink (pbuf, lbuf, SIM_PATHMAX);
2730
2731             /* We trust that the readlink result returns a *relative*
2732                link, or one already adjusted for the file-path-prefix.
2733                (We can't generally tell the difference, so we go with
2734                the easiest decision; no adjustment.)  */
2735
2736             if (nchars == -1)
2737               {
2738                 retval = -cb_host_to_target_errno (cb, errno);
2739                 break;
2740               }
2741
2742             if (bufsiz < nchars)
2743               nchars = bufsiz;
2744
2745             if (sim_core_write_buffer (sd, current_cpu, write_map, lbuf,
2746                                        buf, nchars) != (unsigned int) nchars)
2747               retval = -cb_host_to_target_errno (cb, EFAULT);
2748             else
2749               retval = nchars;
2750
2751             free (pbuf);
2752             free (lbuf_alloc);
2753             break;
2754           }
2755
2756         case TARGET_SYS_sched_getscheduler:
2757           {
2758             USI pid = arg1;
2759
2760             /* FIXME: Search (other) existing threads.  */
2761             if (pid != 0 && pid != TARGET_PID)
2762               retval = -cb_host_to_target_errno (cb, ESRCH);
2763             else
2764               retval = TARGET_SCHED_OTHER;
2765             break;
2766           }
2767
2768         case TARGET_SYS_sched_getparam:
2769           {
2770             USI pid = arg1;
2771             USI paramp = arg2;
2772
2773             /* The kernel says:
2774                struct sched_param {
2775                         int sched_priority;
2776                }; */
2777
2778             if (pid != 0 && pid != TARGET_PID)
2779               retval = -cb_host_to_target_errno (cb, ESRCH);
2780             else
2781               {
2782                 /* FIXME: Save scheduler setting before threads are
2783                    created too.  */
2784                 sim_core_write_unaligned_4 (current_cpu, pc, 0, paramp,
2785                                             current_cpu->thread_data != NULL
2786                                             ? (current_cpu
2787                                                ->thread_data[threadno]
2788                                                .priority)
2789                                             : 0);
2790                 retval = 0;
2791               }
2792             break;
2793           }
2794
2795         case TARGET_SYS_sched_setparam:
2796           {
2797             USI pid = arg1;
2798             USI paramp = arg2;
2799
2800             if ((pid != 0 && pid != TARGET_PID)
2801                 || sim_core_read_unaligned_4 (current_cpu, pc, 0,
2802                                               paramp) != 0)
2803               retval = -cb_host_to_target_errno (cb, EINVAL);
2804             else
2805               retval = 0;
2806             break;
2807           }
2808
2809         case TARGET_SYS_sched_setscheduler:
2810           {
2811             USI pid = arg1;
2812             USI policy = arg2;
2813             USI paramp = arg3;
2814
2815             if ((pid != 0 && pid != TARGET_PID)
2816                 || policy != TARGET_SCHED_OTHER
2817                 || sim_core_read_unaligned_4 (current_cpu, pc, 0,
2818                                               paramp) != 0)
2819               retval = -cb_host_to_target_errno (cb, EINVAL);
2820             else
2821               /* FIXME: Save scheduler setting to be read in later
2822                  sched_getparam calls.  */
2823               retval = 0;
2824             break;
2825           }
2826
2827         case TARGET_SYS_sched_yield:
2828           /* We reschedule to the next thread after a syscall anyway, so
2829              we don't have to do anything here than to set the return
2830              value.  */
2831           retval = 0;
2832           break;
2833
2834         case TARGET_SYS_sched_get_priority_min:
2835         case TARGET_SYS_sched_get_priority_max:
2836           if (arg1 != 0)
2837             retval = -cb_host_to_target_errno (cb, EINVAL);
2838           else
2839             retval = 0;
2840           break;
2841
2842         case TARGET_SYS_ugetrlimit:
2843           {
2844             unsigned int curlim, maxlim;
2845             if (arg1 != TARGET_RLIMIT_STACK && arg1 != TARGET_RLIMIT_NOFILE)
2846               {
2847                 retval = -cb_host_to_target_errno (cb, EINVAL);
2848                 break;
2849               }
2850
2851             /* The kernel says:
2852                struct rlimit {
2853                        unsigned long   rlim_cur;
2854                        unsigned long   rlim_max;
2855                }; */
2856             if (arg1 == TARGET_RLIMIT_NOFILE)
2857               {
2858                 /* Sadly a very low limit.  Better not lie, though.  */
2859                 maxlim = curlim = MAX_CALLBACK_FDS;
2860               }
2861             else /* arg1 == TARGET_RLIMIT_STACK */
2862               {
2863                 maxlim = 0xffffffff;
2864                 curlim = 0x800000;
2865               }
2866             sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, curlim);
2867             sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, maxlim);
2868             retval = 0;
2869             break;
2870           }
2871
2872         case TARGET_SYS_setrlimit:
2873           if (arg1 != TARGET_RLIMIT_STACK)
2874             {
2875               retval = -cb_host_to_target_errno (cb, EINVAL);
2876               break;
2877             }
2878           /* FIXME: Save values for future ugetrlimit calls.  */
2879           retval = 0;
2880           break;
2881
2882         /* Provide a very limited subset of the sysctl functions, and
2883            abort for the rest. */
2884         case TARGET_SYS__sysctl:
2885           {
2886             /* The kernel says:
2887                struct __sysctl_args {
2888                 int *name;
2889                 int nlen;
2890                 void *oldval;
2891                 size_t *oldlenp;
2892                 void *newval;
2893                 size_t newlen;
2894                 unsigned long __unused[4];
2895                }; */
2896             SI name = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1);
2897             SI name0 = name == 0
2898               ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name);
2899             SI name1 = name == 0
2900               ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name + 4);
2901             SI nlen
2902               =  sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 4);
2903             SI oldval
2904               =  sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 8);
2905             SI oldlenp
2906               =  sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 12);
2907             SI oldlen = oldlenp == 0
2908               ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, oldlenp);
2909             SI newval
2910               =  sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 16);
2911             SI newlen
2912               = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 20);
2913
2914             if (name0 == TARGET_CTL_KERN && name1 == TARGET_CTL_KERN_VERSION)
2915               {
2916                 SI to_write = oldlen < (SI) sizeof (TARGET_UTSNAME)
2917                   ? oldlen : (SI) sizeof (TARGET_UTSNAME);
2918
2919                 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldlenp,
2920                                             sizeof (TARGET_UTSNAME));
2921
2922                 if (sim_core_write_buffer (sd, current_cpu, write_map,
2923                                            TARGET_UTSNAME, oldval,
2924                                            to_write)
2925                     != (unsigned int) to_write)
2926                   retval = -cb_host_to_target_errno (cb, EFAULT);
2927                 else
2928                   retval = 0;
2929                 break;
2930               }
2931
2932             retval
2933               = cris_unknown_syscall (current_cpu, pc,
2934                                       "Unimplemented _sysctl syscall "
2935                                       "(0x%lx: [0x%lx, 0x%lx],"
2936                                       " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
2937                                       (unsigned long) name,
2938                                       (unsigned long) name0,
2939                                       (unsigned long) name1,
2940                                       (unsigned long) nlen,
2941                                       (unsigned long) oldval,
2942                                       (unsigned long) oldlenp,
2943                                       (unsigned long) newval,
2944                                       (unsigned long) newlen);
2945             break;
2946           }
2947
2948         case TARGET_SYS_exit:
2949           {
2950             /* Here for all but the last thread.  */
2951             int i;
2952             int pid
2953               = current_cpu->thread_data[threadno].threadid + TARGET_PID;
2954             int ppid
2955               = (current_cpu->thread_data[threadno].parent_threadid
2956                  + TARGET_PID);
2957             int exitsig = current_cpu->thread_data[threadno].exitsig;
2958
2959             /* Any children are now all orphans.  */
2960             for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
2961               if (current_cpu->thread_data[i].parent_threadid
2962                   == current_cpu->thread_data[threadno].threadid)
2963                 /* Make getppid(2) return 1 for them, poor little ones.  */
2964                 current_cpu->thread_data[i].parent_threadid = -TARGET_PID + 1;
2965
2966             /* Free the cpu context data.  When the parent has received
2967                the exit status, we'll clear the entry too.  */
2968             free (current_cpu->thread_data[threadno].cpu_context);
2969             current_cpu->thread_data[threadno].cpu_context = NULL;
2970             current_cpu->m1threads--;
2971             if (arg1 != 0)
2972               {
2973                 sim_io_eprintf (sd, "Thread %d exited with status %d\n",
2974                                 pid, arg1);
2975                 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2976                                  SIM_SIGILL);
2977               }
2978
2979             /* Still, we may want to support non-zero exit values.  */
2980             current_cpu->thread_data[threadno].exitval = arg1 << 8;
2981
2982             if (exitsig)
2983               deliver_signal (current_cpu, exitsig, ppid);
2984             break;
2985           }
2986
2987         case TARGET_SYS_clone:
2988           {
2989             int nthreads = current_cpu->m1threads + 1;
2990             void *thread_cpu_data;
2991             bfd_byte old_sp_buf[4];
2992             bfd_byte sp_buf[4];
2993             const bfd_byte zeros[4] = { 0, 0, 0, 0 };
2994             int i;
2995
2996             /* That's right, the syscall clone arguments are reversed
2997                compared to sys_clone notes in clone(2) and compared to
2998                other Linux ports (i.e. it's the same order as in the
2999                clone(2) libcall).  */
3000             USI flags = arg2;
3001             USI newsp = arg1;
3002
3003             if (nthreads == SIM_TARGET_MAX_THREADS)
3004               {
3005                 retval = -cb_host_to_target_errno (cb, EAGAIN);
3006                 break;
3007               }
3008
3009             /* FIXME: Implement the low byte.  */
3010             if ((flags & ~TARGET_CSIGNAL) !=
3011                 (TARGET_CLONE_VM
3012                  | TARGET_CLONE_FS
3013                  | TARGET_CLONE_FILES
3014                  | TARGET_CLONE_SIGHAND)
3015                 || newsp == 0)
3016               {
3017                 retval
3018                   = cris_unknown_syscall (current_cpu, pc,
3019                                           "Unimplemented clone syscall "
3020                                           "(0x%lx, 0x%lx)\n",
3021                                           (unsigned long) arg1,
3022                                           (unsigned long) arg2);
3023                 break;
3024               }
3025
3026             if (current_cpu->thread_data == NULL)
3027               make_first_thread (current_cpu);
3028
3029             /* The created thread will get the new SP and a cleared R10.
3030                Since it's created out of a copy of the old thread and we
3031                don't have a set-register-function that just take the
3032                cpu_data as a parameter, we set the childs values first,
3033                and write back or overwrite them in the parent after the
3034                copy.  */
3035             (*CPU_REG_FETCH (current_cpu)) (current_cpu,
3036                                             H_GR_SP, old_sp_buf, 4);
3037             bfd_putl32 (newsp, sp_buf);
3038             (*CPU_REG_STORE (current_cpu)) (current_cpu,
3039                                             H_GR_SP, sp_buf, 4);
3040             (*CPU_REG_STORE (current_cpu)) (current_cpu,
3041                                             H_GR_R10, (bfd_byte *) zeros, 4);
3042             thread_cpu_data
3043               = (*current_cpu
3044                  ->make_thread_cpu_data) (current_cpu,
3045                                           &current_cpu->cpu_data_placeholder);
3046             (*CPU_REG_STORE (current_cpu)) (current_cpu,
3047                                             H_GR_SP, old_sp_buf, 4);
3048
3049             retval = ++current_cpu->max_threadid + TARGET_PID;
3050
3051             /* Find an unused slot.  After a few threads have been created
3052                and exited, the array is expected to be a bit fragmented.
3053                We don't reuse the first entry, though, that of the
3054                original thread.  */
3055             for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
3056               if (current_cpu->thread_data[i].cpu_context == NULL
3057                   /* Don't reuse a zombied entry.  */
3058                   && current_cpu->thread_data[i].threadid == 0)
3059                 break;
3060
3061             memcpy (&current_cpu->thread_data[i],
3062                     &current_cpu->thread_data[threadno],
3063                     sizeof (current_cpu->thread_data[i]));
3064             current_cpu->thread_data[i].cpu_context = thread_cpu_data;
3065             current_cpu->thread_data[i].cpu_context_atsignal = NULL;
3066             current_cpu->thread_data[i].threadid = current_cpu->max_threadid;
3067             current_cpu->thread_data[i].parent_threadid
3068               = current_cpu->thread_data[threadno].threadid;
3069             current_cpu->thread_data[i].pipe_read_fd = 0;
3070             current_cpu->thread_data[i].pipe_write_fd = 0;
3071             current_cpu->thread_data[i].at_syscall = 0;
3072             current_cpu->thread_data[i].sigpending = 0;
3073             current_cpu->thread_data[i].sigsuspended = 0;
3074             current_cpu->thread_data[i].exitsig = flags & TARGET_CSIGNAL;
3075             current_cpu->m1threads = nthreads;
3076             break;
3077           }
3078
3079         /* Better watch these in case they do something necessary.  */
3080         case TARGET_SYS_socketcall:
3081           retval = -cb_host_to_target_errno (cb, ENOSYS);
3082           break;
3083
3084         unimplemented_syscall:
3085         default:
3086           retval
3087             = cris_unknown_syscall (current_cpu, pc,
3088                                     "Unimplemented syscall: %d "
3089                                     "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3090                                     callnum, arg1, arg2, arg3, arg4, arg5,
3091                                     arg6);
3092         }
3093     }
3094
3095   /* Minimal support for fcntl F_GETFL as used in open+fdopen.  */
3096   if (callnum == TARGET_SYS_open)
3097     {
3098       current_cpu->last_open_fd = retval;
3099       current_cpu->last_open_flags = arg2;
3100     }
3101
3102   current_cpu->last_syscall = callnum;
3103
3104   /* A system call is a rescheduling point.  For the time being, we don't
3105      reschedule anywhere else.  */
3106   if (current_cpu->m1threads != 0
3107       /* We need to schedule off from an exiting thread that is the
3108          second-last one.  */
3109       || (current_cpu->thread_data != NULL
3110           && current_cpu->thread_data[threadno].cpu_context == NULL))
3111     {
3112       bfd_byte retval_buf[4];
3113
3114       current_cpu->thread_data[threadno].last_execution
3115         = TARGET_TIME_MS (current_cpu);
3116       bfd_putl32 (retval, retval_buf);
3117       (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
3118
3119       current_cpu->thread_data[threadno].at_syscall = 1;
3120       reschedule (current_cpu);
3121
3122       (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
3123       retval = bfd_getl32 (retval_buf);
3124     }
3125
3126   return retval;
3127 }
3128
3129 /* Callback from simulator write saying that the pipe at (reader, writer)
3130    is now non-empty (so the writer should wait until the pipe is empty, at
3131    least not write to this or any other pipe).  Simplest is to just wait
3132    until the pipe is empty.  */
3133
3134 static void
3135 cris_pipe_nonempty (host_callback *cb ATTRIBUTE_UNUSED,
3136                     int reader, int writer)
3137 {
3138   SIM_CPU *cpu = current_cpu_for_cb_callback;
3139   const bfd_byte zeros[4] = { 0, 0, 0, 0 };
3140
3141   /* It's the current thread: we just have to re-run the current
3142      syscall instruction (presumably "break 13") and change the syscall
3143      to the special simulator-wait code.  Oh, and set a marker that
3144      we're waiting, so we can disambiguate the special call from a
3145      program error.
3146
3147      This function may be called multiple times between cris_pipe_empty,
3148      but we must avoid e.g. decreasing PC every time.  Check fd markers
3149      to tell.  */
3150   if (cpu->thread_data == NULL)
3151     {
3152       sim_io_eprintf (CPU_STATE (cpu),
3153                       "Terminating simulation due to writing pipe rd:wr %d:%d"
3154                       " from one single thread\n", reader, writer);
3155       sim_engine_halt (CPU_STATE (cpu), cpu,
3156                        NULL, sim_pc_get (cpu), sim_stopped, SIM_SIGILL);
3157     }
3158   else if (cpu->thread_data[cpu->threadno].pipe_write_fd == 0)
3159     {
3160       cpu->thread_data[cpu->threadno].pipe_write_fd = writer;
3161       cpu->thread_data[cpu->threadno].pipe_read_fd = reader;
3162       /* FIXME: We really shouldn't change registers other than R10 in
3163          syscalls (like R9), here or elsewhere.  */
3164       (*CPU_REG_STORE (cpu)) (cpu, H_GR_R9, (bfd_byte *) zeros, 4);
3165       sim_pc_set (cpu, sim_pc_get (cpu) - 2);
3166     }
3167 }
3168
3169 /* Callback from simulator close or read call saying that the pipe at
3170    (reader, writer) is now empty (so the writer can write again, perhaps
3171    leave a waiting state).  If there are bytes remaining, they couldn't be
3172    consumed (perhaps due to the pipe closing).  */
3173
3174 static void
3175 cris_pipe_empty (host_callback *cb,
3176                  int reader,
3177                  int writer)
3178 {
3179   int i;
3180   SIM_CPU *cpu = current_cpu_for_cb_callback;
3181   bfd_byte r10_buf[4];
3182   int remaining
3183     = cb->pipe_buffer[writer].size - cb->pipe_buffer[reader].size;
3184
3185   /* We need to find the thread that waits for this pipe.  */
3186   for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
3187     if (cpu->thread_data[i].cpu_context
3188         && cpu->thread_data[i].pipe_write_fd == writer)
3189       {
3190         int retval;
3191
3192         /* Temporarily switch to this cpu context, so we can change the
3193            PC by ordinary calls.  */
3194
3195         memcpy (cpu->thread_data[cpu->threadno].cpu_context,
3196                 &cpu->cpu_data_placeholder,
3197                 cpu->thread_cpu_data_size);
3198         memcpy (&cpu->cpu_data_placeholder,
3199                 cpu->thread_data[i].cpu_context,
3200                 cpu->thread_cpu_data_size);
3201
3202         /* The return value is supposed to contain the number of
3203            written bytes, which is the number of bytes requested and
3204            returned at the write call.  You might think the right
3205            thing is to adjust the return-value to be only the
3206            *consumed* number of bytes, but it isn't.  We're only
3207            called if the pipe buffer is fully consumed or it is being
3208            closed, possibly with remaining bytes.  For the latter
3209            case, the writer is still supposed to see success for
3210            PIPE_BUF bytes (a constant which we happen to know and is
3211            unlikely to change).  The return value may also be a
3212            negative number; an error value.  This case is covered
3213            because "remaining" is always >= 0.  */
3214         (*CPU_REG_FETCH (cpu)) (cpu, H_GR_R10, r10_buf, 4);
3215         retval = (int) bfd_getl_signed_32 (r10_buf);
3216         if (retval - remaining > TARGET_PIPE_BUF)
3217           {
3218             bfd_putl32 (retval - remaining, r10_buf);
3219             (*CPU_REG_STORE (cpu)) (cpu, H_GR_R10, r10_buf, 4);
3220           }
3221         sim_pc_set (cpu, sim_pc_get (cpu) + 2);
3222         memcpy (cpu->thread_data[i].cpu_context,
3223                 &cpu->cpu_data_placeholder,
3224                 cpu->thread_cpu_data_size);
3225         memcpy (&cpu->cpu_data_placeholder,
3226                 cpu->thread_data[cpu->threadno].cpu_context,
3227                 cpu->thread_cpu_data_size);
3228         cpu->thread_data[i].pipe_read_fd = 0;
3229         cpu->thread_data[i].pipe_write_fd = 0;
3230         return;
3231       }
3232
3233   abort ();
3234 }
3235
3236 /* We have a simulator-specific notion of time.  See TARGET_TIME.  */
3237
3238 static long
3239 cris_time (host_callback *cb ATTRIBUTE_UNUSED, long *t)
3240 {
3241   long retval = TARGET_TIME (current_cpu_for_cb_callback);
3242   if (t)
3243     *t = retval;
3244   return retval;
3245 }
3246
3247 /* Set target-specific callback data. */
3248
3249 void
3250 cris_set_callbacks (host_callback *cb)
3251 {
3252   /* Yeargh, have to cast away constness to avoid warnings.  */
3253   cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_map;
3254   cb->errno_map = (CB_TARGET_DEFS_MAP *) errno_map;
3255
3256   /* The kernel stat64 layout.  If we see a file > 2G, the "long"
3257      parameter to cb_store_target_endian will make st_size negative.
3258      Similarly for st_ino.  FIXME: Find a 64-bit type, and use it
3259      *unsigned*, and/or add syntax for signed-ness.  */
3260   cb->stat_map = stat_map;
3261   cb->open_map = (CB_TARGET_DEFS_MAP *) open_map;
3262   cb->pipe_nonempty = cris_pipe_nonempty;
3263   cb->pipe_empty = cris_pipe_empty;
3264   cb->time = cris_time;
3265 }
3266
3267 /* Process an address exception.  */
3268
3269 void
3270 cris_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
3271                   unsigned int map, int nr_bytes, address_word addr,
3272                   transfer_type transfer, sim_core_signals sig)
3273 {
3274   sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
3275                    transfer, sig);
3276 }