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