OSDN Git Service

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