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