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