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