* cris/sim-main.h (struct _sim_cpu): New member
[binutils-gdb.git] / sim / cris / traps.c
1 /* CRIS exception, interrupt, and trap (EIT) support
2 Copyright (C) 2004, 2005, 2007, 2008 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 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
759 static SIM_CPU *current_cpu_for_cb_callback;
760
761 static int syscall_read_mem (host_callback *, struct cb_syscall *,
762 unsigned long, char *, int);
763 static int syscall_write_mem (host_callback *, struct cb_syscall *,
764 unsigned long, const char *, int);
765 static USI create_map (SIM_DESC, struct cris_sim_mmapped_page **,
766 USI addr, USI len);
767 static USI unmap_pages (SIM_DESC, struct cris_sim_mmapped_page **,
768 USI addr, USI len);
769 static USI is_mapped (SIM_DESC, struct cris_sim_mmapped_page **,
770 USI addr, USI len);
771 static void dump_statistics (SIM_CPU *current_cpu);
772 static void make_first_thread (SIM_CPU *current_cpu);
773
774 /* Read/write functions for system call interface. */
775
776 static int
777 syscall_read_mem (host_callback *cb ATTRIBUTE_UNUSED,
778 struct cb_syscall *sc,
779 unsigned long taddr, char *buf, int bytes)
780 {
781 SIM_DESC sd = (SIM_DESC) sc->p1;
782 SIM_CPU *cpu = (SIM_CPU *) sc->p2;
783
784 return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
785 }
786
787 static int
788 syscall_write_mem (host_callback *cb ATTRIBUTE_UNUSED,
789 struct cb_syscall *sc,
790 unsigned long taddr, const char *buf, int bytes)
791 {
792 SIM_DESC sd = (SIM_DESC) sc->p1;
793 SIM_CPU *cpu = (SIM_CPU *) sc->p2;
794
795 return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
796 }
797
798 /* When we risk running self-modified code (as in trampolines), this is
799 called from special-case insns. The silicon CRIS CPU:s have enough
800 cache snooping implemented making this a simulator-only issue. Tests:
801 gcc.c-torture/execute/931002-1.c execution, -O3 -g
802 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
803
804 void
805 cris_flush_simulator_decode_cache (SIM_CPU *current_cpu,
806 USI pc ATTRIBUTE_UNUSED)
807 {
808 SIM_DESC sd = CPU_STATE (current_cpu);
809
810 #if WITH_SCACHE
811 if (USING_SCACHE_P (sd))
812 scache_flush_cpu (current_cpu);
813 #endif
814 }
815
816 /* Output statistics at the end of a run. */
817 static void
818 dump_statistics (SIM_CPU *current_cpu)
819 {
820 SIM_DESC sd = CPU_STATE (current_cpu);
821 CRIS_MISC_PROFILE *profp
822 = CPU_CRIS_MISC_PROFILE (current_cpu);
823 unsigned64 total = profp->basic_cycle_count;
824 const char *textmsg = "Basic clock cycles, total @: %llu\n";
825
826 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
827 what's included in the "total" count only. */
828 switch (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
829 & FLAG_CRIS_MISC_PROFILE_ALL)
830 {
831 case FLAG_CRIS_MISC_PROFILE_SIMPLE:
832 break;
833
834 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED | FLAG_CRIS_MISC_PROFILE_SIMPLE):
835 textmsg
836 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
837 total += profp->unaligned_mem_dword_count;
838 break;
839
840 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE | FLAG_CRIS_MISC_PROFILE_SIMPLE):
841 textmsg = "Schedulable clock cycles, total @: %llu\n";
842 total
843 += (profp->memsrc_stall_count
844 + profp->memraw_stall_count
845 + profp->movemsrc_stall_count
846 + profp->movemdst_stall_count
847 + profp->mulsrc_stall_count
848 + profp->jumpsrc_stall_count
849 + profp->unaligned_mem_dword_count);
850 break;
851
852 case FLAG_CRIS_MISC_PROFILE_ALL:
853 textmsg = "All accounted clock cycles, total @: %llu\n";
854 total
855 += (profp->memsrc_stall_count
856 + profp->memraw_stall_count
857 + profp->movemsrc_stall_count
858 + profp->movemdst_stall_count
859 + profp->movemaddr_stall_count
860 + profp->mulsrc_stall_count
861 + profp->jumpsrc_stall_count
862 + profp->branch_stall_count
863 + profp->jumptarget_stall_count
864 + profp->unaligned_mem_dword_count);
865 break;
866
867 default:
868 abort ();
869
870 sim_io_eprintf (sd,
871 "Internal inconsistency at %s:%d",
872 __FILE__, __LINE__);
873 sim_engine_halt (sd, current_cpu, NULL, 0,
874 sim_stopped, SIM_SIGILL);
875 }
876
877 /* Historically, these messages have gone to stderr, so we'll keep it
878 that way. It's also easier to then tell it from normal program
879 output. FIXME: Add redirect option like "run -e file". */
880 sim_io_eprintf (sd, textmsg, total);
881
882 /* For v32, unaligned_mem_dword_count should always be 0. For
883 v10, memsrc_stall_count should always be 0. */
884 sim_io_eprintf (sd, "Memory source stall cycles: %llu\n",
885 (unsigned long long) (profp->memsrc_stall_count
886 + profp->unaligned_mem_dword_count));
887 sim_io_eprintf (sd, "Memory read-after-write stall cycles: %llu\n",
888 (unsigned long long) profp->memraw_stall_count);
889 sim_io_eprintf (sd, "Movem source stall cycles: %llu\n",
890 (unsigned long long) profp->movemsrc_stall_count);
891 sim_io_eprintf (sd, "Movem destination stall cycles: %llu\n",
892 (unsigned long long) profp->movemdst_stall_count);
893 sim_io_eprintf (sd, "Movem address stall cycles: %llu\n",
894 (unsigned long long) profp->movemaddr_stall_count);
895 sim_io_eprintf (sd, "Multiplication source stall cycles: %llu\n",
896 (unsigned long long) profp->mulsrc_stall_count);
897 sim_io_eprintf (sd, "Jump source stall cycles: %llu\n",
898 (unsigned long long) profp->jumpsrc_stall_count);
899 sim_io_eprintf (sd, "Branch misprediction stall cycles: %llu\n",
900 (unsigned long long) profp->branch_stall_count);
901 sim_io_eprintf (sd, "Jump target stall cycles: %llu\n",
902 (unsigned long long) profp->jumptarget_stall_count);
903 }
904
905 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
906 Return 1 if a overlap detected, 0 otherwise. */
907
908 static USI
909 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED,
910 struct cris_sim_mmapped_page **rootp,
911 USI addr, USI len)
912 {
913 struct cris_sim_mmapped_page *mapp;
914
915 if (len == 0 || (len & 8191))
916 abort ();
917
918 /* Iterate over the reverse-address sorted pages until we find a page in
919 or lower than the checked area. */
920 for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
921 if (mapp->addr < addr + len && mapp->addr >= addr)
922 return 1;
923
924 return 0;
925 }
926
927 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
928 Return 1 if the whole area is mapped, 0 otherwise. */
929
930 static USI
931 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED,
932 struct cris_sim_mmapped_page **rootp,
933 USI addr, USI len)
934 {
935 struct cris_sim_mmapped_page *mapp;
936
937 if (len == 0 || (len & 8191))
938 abort ();
939
940 /* Iterate over the reverse-address sorted pages until we find a page
941 lower than the checked area. */
942 for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
943 if (addr == mapp->addr && len == 8192)
944 return 1;
945 else if (addr + len > mapp->addr)
946 len -= 8192;
947
948 return 0;
949 }
950
951 /* Debug helper; to be run from gdb. */
952
953 void
954 cris_dump_map (SIM_CPU *current_cpu)
955 {
956 struct cris_sim_mmapped_page *mapp;
957 USI start, end;
958
959 for (mapp = current_cpu->highest_mmapped_page,
960 start = mapp == NULL ? 0 : mapp->addr + 8192,
961 end = mapp == NULL ? 0 : mapp->addr + 8191;
962 mapp != NULL;
963 mapp = mapp->prev)
964 {
965 if (mapp->addr != start - 8192)
966 {
967 sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
968 end = mapp->addr + 8191;
969 }
970
971 start = mapp->addr;
972 }
973
974 if (current_cpu->highest_mmapped_page != NULL)
975 sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
976 }
977
978 /* Create mmapped memory. */
979
980 static USI
981 create_map (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
982 USI len)
983 {
984 struct cris_sim_mmapped_page *mapp;
985 struct cris_sim_mmapped_page **higher_prevp = rootp;
986 USI new_addr = 0x40000000;
987
988 if (addr != 0)
989 new_addr = addr;
990 else if (*rootp)
991 new_addr = rootp[0]->addr + 8192;
992
993 if (len != 8192)
994 {
995 USI page_addr;
996
997 if (len & 8191)
998 /* Which is better: return an error for this, or just round it up? */
999 abort ();
1000
1001 /* Do a recursive call for each page in the request. */
1002 for (page_addr = new_addr; len != 0; page_addr += 8192, len -= 8192)
1003 if (create_map (sd, rootp, page_addr, 8192) >= (USI) -8191)
1004 abort ();
1005
1006 return new_addr;
1007 }
1008
1009 for (mapp = *rootp;
1010 mapp != NULL && mapp->addr > new_addr;
1011 mapp = mapp->prev)
1012 higher_prevp = &mapp->prev;
1013
1014 /* Allocate the new page, on the next higher page from the last one
1015 allocated, and link in the new descriptor before previous ones. */
1016 mapp = malloc (sizeof (*mapp));
1017
1018 if (mapp == NULL)
1019 return (USI) -ENOMEM;
1020
1021 sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
1022 new_addr, len,
1023 0, NULL, NULL);
1024
1025 mapp->addr = new_addr;
1026 mapp->prev = *higher_prevp;
1027 *higher_prevp = mapp;
1028
1029 return new_addr;
1030 }
1031
1032 /* Unmap one or more pages. */
1033
1034 static USI
1035 unmap_pages (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
1036 USI len)
1037 {
1038 struct cris_sim_mmapped_page *mapp;
1039 struct cris_sim_mmapped_page **higher_prevp = rootp;
1040
1041 if (len != 8192)
1042 {
1043 USI page_addr;
1044
1045 if (len & 8191)
1046 /* Which is better: return an error for this, or just round it up? */
1047 abort ();
1048
1049 /* Loop backwards to make each call is O(1) over the number of pages
1050 allocated, if we're unmapping from the high end of the pages. */
1051 for (page_addr = addr + len - 8192;
1052 page_addr >= addr;
1053 page_addr -= 8192)
1054 if (unmap_pages (sd, rootp, page_addr, 8192) != 0)
1055 abort ();
1056
1057 return 0;
1058 }
1059
1060 for (mapp = *rootp; mapp != NULL && mapp->addr > addr; mapp = mapp->prev)
1061 higher_prevp = &mapp->prev;
1062
1063 if (mapp == NULL || mapp->addr != addr)
1064 return EINVAL;
1065
1066 *higher_prevp = mapp->prev;
1067 sim_core_detach (sd, NULL, 0, 0, addr);
1068 free (mapp);
1069 return 0;
1070 }
1071
1072 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1073
1074 SEM_PC
1075 sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
1076 {
1077 SIM_DESC sd = CPU_STATE (current_cpu);
1078
1079 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
1080 return vpc;
1081 }
1082
1083 /* Handlers from the CGEN description that should not be called. */
1084
1085 USI
1086 cris_bmod_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
1087 UINT srcreg ATTRIBUTE_UNUSED,
1088 USI dstreg ATTRIBUTE_UNUSED)
1089 {
1090 abort ();
1091 }
1092
1093 void
1094 h_supr_set_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
1095 UINT index ATTRIBUTE_UNUSED,
1096 USI page ATTRIBUTE_UNUSED,
1097 USI newval ATTRIBUTE_UNUSED)
1098 {
1099 abort ();
1100 }
1101
1102 USI
1103 h_supr_get_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
1104 UINT index ATTRIBUTE_UNUSED,
1105 USI page ATTRIBUTE_UNUSED)
1106 {
1107 abort ();
1108 }
1109
1110 /* Swap one context for another. */
1111
1112 static void
1113 schedule (SIM_CPU *current_cpu, int next)
1114 {
1115 /* Need to mark context-switches in the trace output. */
1116 if ((CPU_CRIS_MISC_PROFILE (current_cpu)->flags
1117 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE))
1118 cris_trace_printf (CPU_STATE (current_cpu), current_cpu,
1119 "\t#:%d\n", next);
1120
1121 /* Copy the current context (if there is one) to its slot. */
1122 if (current_cpu->thread_data[current_cpu->threadno].cpu_context)
1123 memcpy (current_cpu->thread_data[current_cpu->threadno].cpu_context,
1124 &current_cpu->cpu_data_placeholder,
1125 current_cpu->thread_cpu_data_size);
1126
1127 /* Copy the new context from its slot. */
1128 memcpy (&current_cpu->cpu_data_placeholder,
1129 current_cpu->thread_data[next].cpu_context,
1130 current_cpu->thread_cpu_data_size);
1131
1132 /* Update needed stuff to indicate the new context. */
1133 current_cpu->threadno = next;
1134
1135 /* Handle pending signals. */
1136 if (current_cpu->thread_data[next].sigpending
1137 /* We don't run nested signal handlers. This means that pause(2)
1138 and sigsuspend(2) do not work in sighandlers, but that
1139 shouldn't be too hard a restriction. It also greatly
1140 simplifies the code. */
1141 && current_cpu->thread_data[next].cpu_context_atsignal == NULL)
1142 {
1143 int sig;
1144
1145 /* See if there's really a pending, non-blocked handler. We don't
1146 queue signals, so just use the first one in ascending order. */
1147 for (sig = 0; sig < 64; sig++)
1148 if (current_cpu->thread_data[next].sigdata[sig].pending
1149 && !current_cpu->thread_data[next].sigdata[sig].blocked)
1150 {
1151 bfd_byte regbuf[4];
1152 USI sp;
1153 int i;
1154 USI blocked;
1155 USI pc = sim_pc_get (current_cpu);
1156
1157 /* It's simpler to save the CPU context inside the simulator
1158 than on the stack. */
1159 current_cpu->thread_data[next].cpu_context_atsignal
1160 = (*current_cpu
1161 ->make_thread_cpu_data) (current_cpu,
1162 current_cpu->thread_data[next]
1163 .cpu_context);
1164
1165 (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
1166 sp = bfd_getl32 (regbuf);
1167
1168 /* Make sure we have an aligned stack. */
1169 sp &= ~3;
1170
1171 /* Make room for the signal frame, aligned. FIXME: Check that
1172 the memory exists, map it in if absent. (BTW, should also
1173 implement on-access automatic stack allocation). */
1174 sp -= 20;
1175
1176 /* This isn't the same signal frame as the kernel uses, because
1177 we don't want to bother getting all registers on and off the
1178 stack. */
1179
1180 /* First, we store the currently blocked signals. */
1181 blocked = 0;
1182 for (i = 0; i < 32; i++)
1183 blocked
1184 |= current_cpu->thread_data[next].sigdata[i + 1].blocked << i;
1185 sim_core_write_aligned_4 (current_cpu, pc, 0, sp, blocked);
1186 blocked = 0;
1187 for (i = 0; i < 31; i++)
1188 blocked
1189 |= current_cpu->thread_data[next].sigdata[i + 33].blocked << i;
1190 sim_core_write_aligned_4 (current_cpu, pc, 0, sp + 4, blocked);
1191
1192 /* Then, the actual instructions. This is CPU-specific, but we
1193 use instructions from the common subset for v10 and v32 which
1194 should be safe for the time being but could be parametrized
1195 if need be. */
1196 /* MOVU.W [PC+],R9. */
1197 sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 8, 0x9c5f);
1198 /* .WORD TARGET_SYS_sigreturn. */
1199 sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 10,
1200 TARGET_SYS_sigreturn);
1201 /* BREAK 13. */
1202 sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 12, 0xe93d);
1203
1204 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1205 instruction. Still, it doesn't matter because v10 has no
1206 delay slot for BREAK so it will not be executed). */
1207 sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 16, 0x05b0);
1208
1209 /* Modify registers to hold the right values for the sighandler
1210 context: updated stackpointer and return address pointing to
1211 the sigreturn stub. */
1212 bfd_putl32 (sp, regbuf);
1213 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
1214 bfd_putl32 (sp + 8, regbuf);
1215 (*CPU_REG_STORE (current_cpu)) (current_cpu, TARGET_SRP_REGNUM,
1216 regbuf, 4);
1217
1218 current_cpu->thread_data[next].sigdata[sig].pending = 0;
1219
1220 /* Block this signal (for the duration of the sighandler). */
1221 current_cpu->thread_data[next].sigdata[sig].blocked = 1;
1222
1223 sim_pc_set (current_cpu, current_cpu->sighandler[sig]);
1224 bfd_putl32 (sig, regbuf);
1225 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10,
1226 regbuf, 4);
1227
1228 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1229 needed all this for, specifies a SA_SIGINFO call but treats it
1230 like an ordinary sighandler; only the signal number argument is
1231 inspected. To make future need to implement SA_SIGINFO
1232 correctly possible, we set the siginfo argument register to a
1233 magic (hopefully non-address) number. (NB: then, you should
1234 just need to pass the siginfo argument; it seems you probably
1235 don't need to implement the specific rt_sigreturn.) */
1236 bfd_putl32 (0xbad5161f, regbuf);
1237 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R11,
1238 regbuf, 4);
1239
1240 /* The third argument is unused and the kernel sets it to 0. */
1241 bfd_putl32 (0, regbuf);
1242 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R12,
1243 regbuf, 4);
1244 return;
1245 }
1246
1247 /* No, there actually was no pending signal for this thread. Reset
1248 this flag. */
1249 current_cpu->thread_data[next].sigpending = 0;
1250 }
1251 }
1252
1253 /* Reschedule the simplest possible way until something else is absolutely
1254 necessary:
1255 - A. Find the next process (round-robin) that doesn't have at_syscall
1256 set, schedule it.
1257 - B. If there is none, just run the next process, round-robin.
1258 - Clear at_syscall for the current process. */
1259
1260 static void
1261 reschedule (SIM_CPU *current_cpu)
1262 {
1263 int i;
1264
1265 /* Iterate over all thread slots, because after a few thread creations
1266 and exits, we don't know where the live ones are. */
1267 for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
1268 i != current_cpu->threadno;
1269 i = (i + 1) % SIM_TARGET_MAX_THREADS)
1270 if (current_cpu->thread_data[i].cpu_context
1271 && current_cpu->thread_data[i].at_syscall == 0)
1272 {
1273 schedule (current_cpu, i);
1274 return;
1275 }
1276
1277 /* Pick any next live thread. */
1278 for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
1279 i != current_cpu->threadno;
1280 i = (i + 1) % SIM_TARGET_MAX_THREADS)
1281 if (current_cpu->thread_data[i].cpu_context)
1282 {
1283 schedule (current_cpu, i);
1284 return;
1285 }
1286
1287 /* More than one live thread, but we couldn't find the next one? */
1288 abort ();
1289 }
1290
1291 /* Set up everything to receive (or IGN) an incoming signal to the
1292 current context. */
1293
1294 static int
1295 deliver_signal (SIM_CPU *current_cpu, int sig, unsigned int pid)
1296 {
1297 int i;
1298 USI pc = sim_pc_get (current_cpu);
1299
1300 /* Find the thread index of the pid. */
1301 for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
1302 /* Apparently it's ok to send signals to zombies (so a check for
1303 current_cpu->thread_data[i].cpu_context != NULL would be
1304 wrong). */
1305 if (current_cpu->thread_data[i].threadid == pid - TARGET_PID)
1306 {
1307 if (sig < 64)
1308 switch (current_cpu->sighandler[sig])
1309 {
1310 case TARGET_SIG_DFL:
1311 switch (sig)
1312 {
1313 /* The following according to the glibc
1314 documentation. (The kernel code has non-obvious
1315 execution paths.) */
1316 case TARGET_SIGFPE:
1317 case TARGET_SIGILL:
1318 case TARGET_SIGSEGV:
1319 case TARGET_SIGBUS:
1320 case TARGET_SIGABRT:
1321 case TARGET_SIGTRAP:
1322 case TARGET_SIGSYS:
1323
1324 case TARGET_SIGTERM:
1325 case TARGET_SIGINT:
1326 case TARGET_SIGQUIT:
1327 case TARGET_SIGKILL:
1328 case TARGET_SIGHUP:
1329
1330 case TARGET_SIGALRM:
1331 case TARGET_SIGVTALRM:
1332 case TARGET_SIGPROF:
1333 case TARGET_SIGSTOP:
1334
1335 case TARGET_SIGPIPE:
1336 case TARGET_SIGLOST:
1337 case TARGET_SIGXCPU:
1338 case TARGET_SIGXFSZ:
1339 case TARGET_SIGUSR1:
1340 case TARGET_SIGUSR2:
1341 sim_io_eprintf (CPU_STATE (current_cpu),
1342 "Exiting pid %d due to signal %d\n",
1343 pid, sig);
1344 sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
1345 NULL, pc, sim_stopped,
1346 sig == TARGET_SIGABRT
1347 ? SIM_SIGABRT : SIM_SIGILL);
1348 return 0;
1349
1350 /* The default for all other signals is to be ignored. */
1351 default:
1352 return 0;
1353 }
1354
1355 case TARGET_SIG_IGN:
1356 switch (sig)
1357 {
1358 case TARGET_SIGKILL:
1359 case TARGET_SIGSTOP:
1360 /* Can't ignore these signals. */
1361 sim_io_eprintf (CPU_STATE (current_cpu),
1362 "Exiting pid %d due to signal %d\n",
1363 pid, sig);
1364 sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
1365 NULL, pc, sim_stopped, SIM_SIGILL);
1366 return 0;
1367
1368 default:
1369 return 0;
1370 }
1371 break;
1372
1373 default:
1374 /* Mark the signal as pending, making schedule () check
1375 closer. The signal will be handled when the thread is
1376 scheduled and the signal is unblocked. */
1377 current_cpu->thread_data[i].sigdata[sig].pending = 1;
1378 current_cpu->thread_data[i].sigpending = 1;
1379 return 0;
1380 }
1381 else
1382 {
1383 sim_io_eprintf (CPU_STATE (current_cpu),
1384 "Unimplemented signal: %d\n", sig);
1385 sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc,
1386 sim_stopped, SIM_SIGILL);
1387 }
1388 }
1389
1390 return
1391 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu)),
1392 ESRCH);
1393 }
1394
1395 /* Make the vector and the first item, the main thread. */
1396
1397 static void
1398 make_first_thread (SIM_CPU *current_cpu)
1399 {
1400 current_cpu->thread_data
1401 = xcalloc (1,
1402 SIM_TARGET_MAX_THREADS
1403 * sizeof (current_cpu->thread_data[0]));
1404 current_cpu->thread_data[0].cpu_context
1405 = (*current_cpu->make_thread_cpu_data) (current_cpu,
1406 &current_cpu
1407 ->cpu_data_placeholder);
1408 current_cpu->thread_data[0].parent_threadid = -1;
1409
1410 /* For good measure. */
1411 if (TARGET_SIG_DFL != 0)
1412 abort ();
1413 }
1414
1415 /* Handle unknown system calls. Returns (if it does) the syscall
1416 return value. */
1417
1418 static USI
1419 cris_unknown_syscall (SIM_CPU *current_cpu, USI pc, char *s, ...)
1420 {
1421 SIM_DESC sd = CPU_STATE (current_cpu);
1422 host_callback *cb = STATE_CALLBACK (sd);
1423
1424 if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP
1425 || cris_unknown_syscall_action == CRIS_USYSC_MSG_ENOSYS)
1426 {
1427 va_list ap;
1428
1429 va_start (ap, s);
1430 sim_io_evprintf (sd, s, ap);
1431 va_end (ap);
1432
1433 if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP)
1434 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
1435 }
1436
1437 return -cb_host_to_target_errno (cb, ENOSYS);
1438 }
1439
1440 /* Main function: the handler of the "break 13" syscall insn. */
1441
1442 USI
1443 cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
1444 USI arg2, USI arg3, USI arg4, USI arg5, USI arg6,
1445 USI pc)
1446 {
1447 CB_SYSCALL s;
1448 SIM_DESC sd = CPU_STATE (current_cpu);
1449 host_callback *cb = STATE_CALLBACK (sd);
1450 int retval;
1451 int threadno = current_cpu->threadno;
1452
1453 current_cpu->syscalls++;
1454
1455 CB_SYSCALL_INIT (&s);
1456 s.func = callnum;
1457 s.arg1 = arg1;
1458 s.arg2 = arg2;
1459 s.arg3 = arg3;
1460
1461 if (callnum == TARGET_SYS_exit_group
1462 || (callnum == TARGET_SYS_exit && current_cpu->m1threads == 0))
1463 {
1464 if (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
1465 & FLAG_CRIS_MISC_PROFILE_ALL)
1466 dump_statistics (current_cpu);
1467 sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, arg1);
1468 }
1469
1470 s.p1 = (PTR) sd;
1471 s.p2 = (PTR) current_cpu;
1472 s.read_mem = syscall_read_mem;
1473 s.write_mem = syscall_write_mem;
1474
1475 current_cpu_for_cb_callback = current_cpu;
1476
1477 if (cb_syscall (cb, &s) != CB_RC_OK)
1478 {
1479 abort ();
1480 sim_io_eprintf (sd, "Break 13: invalid %d? Returned %ld\n", callnum,
1481 s.result);
1482 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
1483 }
1484
1485 retval = s.result == -1 ? -s.errcode : s.result;
1486
1487 if (s.errcode != 0 && s.errcode == cb_host_to_target_errno (cb, ENOSYS))
1488 {
1489 /* If the generic simulator call said ENOSYS, then let's try the
1490 ones we know ourselves.
1491
1492 The convention is to provide *very limited* functionality on an
1493 as-needed basis, only what's covered by the test-suite, tests
1494 added when functionality changes and abort with a descriptive
1495 message for *everything* else. Where there's no test-case, we
1496 just abort. */
1497 switch (callnum)
1498 {
1499 case 0:
1500 /* It's a pretty safe bet that the "old setup() system call"
1501 number will not be re-used; we can't say the same for higher
1502 numbers. We treat this simulator-generated call as "wait
1503 forever"; we re-run this insn. The wait is ended by a
1504 callback. Sanity check that this is the reason we got
1505 here. */
1506 if (current_cpu->thread_data == NULL
1507 || (current_cpu->thread_data[threadno].pipe_write_fd == 0))
1508 goto unimplemented_syscall;
1509
1510 sim_pc_set (current_cpu, pc);
1511 retval = arg1;
1512 break;
1513
1514 case TARGET_SYS_fcntl64:
1515 case TARGET_SYS_fcntl:
1516 switch (arg2)
1517 {
1518 case 1:
1519 /* F_GETFD.
1520 Glibc checks stdin, stdout and stderr fd:s for
1521 close-on-exec security sanity. We just need to provide a
1522 OK return value. If we really need to have a
1523 close-on-exec flag true, we could just do a real fcntl
1524 here. */
1525 retval = 0;
1526 break;
1527
1528 case 2:
1529 /* F_SETFD. Just ignore attempts to set the close-on-exec
1530 flag. */
1531 retval = 0;
1532 break;
1533
1534 case 3:
1535 /* F_GETFL. Check for the special case for open+fdopen. */
1536 if (current_cpu->last_syscall == TARGET_SYS_open
1537 && arg1 == current_cpu->last_open_fd)
1538 {
1539 retval = current_cpu->last_open_flags & TARGET_O_ACCMODE;
1540 break;
1541 }
1542 else if (arg1 == 0)
1543 {
1544 /* Because we can't freopen fd:s 0, 1, 2 to mean
1545 something else than stdin, stdout and stderr
1546 (sim/common/syscall.c:cb_syscall special cases fd
1547 0, 1 and 2), we know what flags that we can
1548 sanely return for these fd:s. */
1549 retval = TARGET_O_RDONLY;
1550 break;
1551 }
1552 else if (arg1 == 1 || arg1 == 2)
1553 {
1554 retval = TARGET_O_WRONLY;
1555 break;
1556 }
1557 /* FALLTHROUGH */
1558 default:
1559 /* Nothing else is implemented. */
1560 retval
1561 = cris_unknown_syscall (current_cpu, pc,
1562 "Unimplemented %s syscall "
1563 "(fd: 0x%lx: cmd: 0x%lx arg: "
1564 "0x%lx)\n",
1565 callnum == TARGET_SYS_fcntl
1566 ? "fcntl" : "fcntl64",
1567 (unsigned long) (USI) arg1,
1568 (unsigned long) (USI) arg2,
1569 (unsigned long) (USI) arg3);
1570 break;
1571 }
1572 break;
1573
1574 case TARGET_SYS_uname:
1575 {
1576 /* Fill in a few constants to appease glibc. */
1577 static char sim_utsname[6][65] =
1578 {
1579 "Linux",
1580 "sim-target",
1581 "2.6.27",
1582 TARGET_UTSNAME,
1583 "cris", /* Overwritten below. */
1584 "localdomain"
1585 };
1586
1587 /* Having the hardware type in Linux equal to the bfd
1588 printable name is deliberate: if you make config.guess
1589 work on your Linux-type system the usual way, it
1590 probably will; either the bfd printable_name or the
1591 ambiguous arch_name. */
1592 strcpy (sim_utsname[4], STATE_ARCHITECTURE (sd)->printable_name);
1593
1594 if ((s.write_mem) (cb, &s, arg1, (const char *) sim_utsname,
1595 sizeof (sim_utsname))
1596 != sizeof (sim_utsname))
1597 retval = -cb_host_to_target_errno (cb, EFAULT);
1598 else
1599 retval = 0;
1600 break;
1601 }
1602
1603 case TARGET_SYS_geteuid32:
1604 /* We tell the truth with these. Maybe we shouldn't, but it
1605 should match the "stat" information. */
1606 retval = geteuid ();
1607 break;
1608
1609 case TARGET_SYS_getuid32:
1610 retval = getuid ();
1611 break;
1612
1613 case TARGET_SYS_getegid32:
1614 retval = getegid ();
1615 break;
1616
1617 case TARGET_SYS_getgid32:
1618 retval = getgid ();
1619 break;
1620
1621 case TARGET_SYS_brk:
1622 /* Most often, we just return the argument, like the Linux
1623 kernel. */
1624 retval = arg1;
1625
1626 if (arg1 == 0)
1627 retval = current_cpu->endbrk;
1628 else if (arg1 <= current_cpu->endmem)
1629 current_cpu->endbrk = arg1;
1630 else
1631 {
1632 USI new_end = (arg1 + 8191) & ~8191;
1633
1634 /* If the simulator wants to brk more than a certain very
1635 large amount, something is wrong. FIXME: Return an error
1636 or abort? Have command-line selectable? */
1637 if (new_end - current_cpu->endmem > SIM_MAX_ALLOC_CHUNK)
1638 {
1639 current_cpu->endbrk = current_cpu->endmem;
1640 retval = current_cpu->endmem;
1641 break;
1642 }
1643
1644 sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
1645 current_cpu->endmem,
1646 new_end - current_cpu->endmem,
1647 0, NULL, NULL);
1648 current_cpu->endbrk = arg1;
1649 current_cpu->endmem = new_end;
1650 }
1651 break;
1652
1653 case TARGET_SYS_getpid:
1654 /* Correct until CLONE_THREAD is implemented. */
1655 retval = current_cpu->thread_data == NULL
1656 ? TARGET_PID
1657 : TARGET_PID + current_cpu->thread_data[threadno].threadid;
1658 break;
1659
1660 case TARGET_SYS_getppid:
1661 /* Correct until CLONE_THREAD is implemented. */
1662 retval = current_cpu->thread_data == NULL
1663 ? TARGET_PID - 1
1664 : (TARGET_PID
1665 + current_cpu->thread_data[threadno].parent_threadid);
1666 break;
1667
1668 case TARGET_SYS_mmap2:
1669 {
1670 USI addr = arg1;
1671 USI len = arg2;
1672 USI prot = arg3;
1673 USI flags = arg4;
1674 USI fd = arg5;
1675 USI pgoff = arg6;
1676
1677 /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1678 still masked away this bit, so let's just ignore
1679 it. */
1680 flags &= ~TARGET_MAP_DENYWRITE;
1681
1682 /* If the simulator wants to mmap more than the very large
1683 limit, something is wrong. FIXME: Return an error or
1684 abort? Have command-line selectable? */
1685 if (len > SIM_MAX_ALLOC_CHUNK)
1686 {
1687 retval = -cb_host_to_target_errno (cb, ENOMEM);
1688 break;
1689 }
1690
1691 if ((prot != (TARGET_PROT_READ | TARGET_PROT_WRITE)
1692 && (prot
1693 != (TARGET_PROT_READ
1694 | TARGET_PROT_WRITE
1695 | TARGET_PROT_EXEC))
1696 && (prot != (TARGET_PROT_READ | TARGET_PROT_EXEC))
1697 && prot != TARGET_PROT_READ)
1698 || (flags != (TARGET_MAP_ANONYMOUS | TARGET_MAP_PRIVATE)
1699 && flags != TARGET_MAP_PRIVATE
1700 && flags != (TARGET_MAP_ANONYMOUS
1701 | TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
1702 && flags != (TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
1703 && flags != TARGET_MAP_SHARED)
1704 || (fd != (USI) -1
1705 && prot != TARGET_PROT_READ
1706 && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
1707 && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
1708 || (fd == (USI) -1 && pgoff != 0)
1709 || (fd != (USI) -1 && (flags & TARGET_MAP_ANONYMOUS))
1710 || ((flags & TARGET_MAP_FIXED) == 0
1711 && is_mapped (sd, &current_cpu->highest_mmapped_page,
1712 addr, (len + 8191) & ~8191)))
1713 {
1714 retval
1715 = cris_unknown_syscall (current_cpu, pc,
1716 "Unimplemented mmap2 call "
1717 "(0x%lx, 0x%lx, 0x%lx, "
1718 "0x%lx, 0x%lx, 0x%lx)\n",
1719 (unsigned long) arg1,
1720 (unsigned long) arg2,
1721 (unsigned long) arg3,
1722 (unsigned long) arg4,
1723 (unsigned long) arg5,
1724 (unsigned long) arg6);
1725 break;
1726 }
1727 else if (fd != (USI) -1)
1728 {
1729 /* Map a file. */
1730
1731 USI newaddr;
1732 USI pos;
1733
1734 /* A non-aligned argument is allowed for files. */
1735 USI newlen = (len + 8191) & ~8191;
1736
1737 /* We only support read, read|exec, and read|write,
1738 which we should already have checked. Check again
1739 anyway. */
1740 if (prot != TARGET_PROT_READ
1741 && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
1742 && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
1743 abort ();
1744
1745 if ((flags & TARGET_MAP_FIXED)
1746 && unmap_pages (sd, &current_cpu->highest_mmapped_page,
1747 addr, newlen) != 0)
1748 abort ();
1749
1750 newaddr
1751 = create_map (sd, &current_cpu->highest_mmapped_page, addr,
1752 newlen);
1753
1754 if (newaddr >= (USI) -8191)
1755 {
1756 abort ();
1757 retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
1758 break;
1759 }
1760
1761 /* We were asked for MAP_FIXED, but couldn't. */
1762 if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
1763 {
1764 abort ();
1765 unmap_pages (sd, &current_cpu->highest_mmapped_page,
1766 newaddr, newlen);
1767 retval = -cb_host_to_target_errno (cb, EINVAL);
1768 break;
1769 }
1770
1771 /* Find the current position in the file. */
1772 s.func = TARGET_SYS_lseek;
1773 s.arg1 = fd;
1774 s.arg2 = 0;
1775 s.arg3 = SEEK_CUR;
1776 if (cb_syscall (cb, &s) != CB_RC_OK)
1777 abort ();
1778 pos = s.result;
1779
1780 if (s.result < 0)
1781 abort ();
1782
1783 /* Move to the correct offset in the file. */
1784 s.func = TARGET_SYS_lseek;
1785 s.arg1 = fd;
1786 s.arg2 = pgoff*8192;
1787 s.arg3 = SEEK_SET;
1788 if (cb_syscall (cb, &s) != CB_RC_OK)
1789 abort ();
1790
1791 if (s.result < 0)
1792 abort ();
1793
1794 /* Use the standard read callback to read in "len"
1795 bytes. */
1796 s.func = TARGET_SYS_read;
1797 s.arg1 = fd;
1798 s.arg2 = newaddr;
1799 s.arg3 = len;
1800 if (cb_syscall (cb, &s) != CB_RC_OK)
1801 abort ();
1802
1803 if ((USI) s.result != len)
1804 abort ();
1805
1806 /* After reading, we need to go back to the previous
1807 position in the file. */
1808 s.func = TARGET_SYS_lseek;
1809 s.arg1 = fd;
1810 s.arg2 = pos;
1811 s.arg3 = SEEK_SET;
1812 if (cb_syscall (cb, &s) != CB_RC_OK)
1813 abort ();
1814 if (pos != (USI) s.result)
1815 abort ();
1816
1817 retval = newaddr;
1818 }
1819 else
1820 {
1821 USI newlen = (len + 8191) & ~8191;
1822 USI newaddr;
1823
1824 if ((flags & TARGET_MAP_FIXED)
1825 && unmap_pages (sd, &current_cpu->highest_mmapped_page,
1826 addr, newlen) != 0)
1827 abort ();
1828
1829 newaddr = create_map (sd, &current_cpu->highest_mmapped_page, addr,
1830 newlen);
1831
1832 if (newaddr >= (USI) -8191)
1833 retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
1834 else
1835 retval = newaddr;
1836
1837 if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
1838 {
1839 abort ();
1840 unmap_pages (sd, &current_cpu->highest_mmapped_page,
1841 newaddr, newlen);
1842 retval = -cb_host_to_target_errno (cb, EINVAL);
1843 break;
1844 }
1845 }
1846 break;
1847 }
1848
1849 case TARGET_SYS_mprotect:
1850 {
1851 /* We only cover the case of linuxthreads mprotecting out
1852 its stack guard page and of dynamic loading mprotecting
1853 away the data (for some reason the whole library, then
1854 mprotects away the data part and mmap-FIX:es it again. */
1855 USI addr = arg1;
1856 USI len = arg2;
1857 USI prot = arg3;
1858
1859 if (prot != TARGET_PROT_NONE
1860 || !is_mapped_only (sd, &current_cpu->highest_mmapped_page,
1861 addr, (len + 8191) & ~8191))
1862 {
1863 retval
1864 = cris_unknown_syscall (current_cpu, pc,
1865 "Unimplemented mprotect call "
1866 "(0x%lx, 0x%lx, 0x%lx)\n",
1867 (unsigned long) arg1,
1868 (unsigned long) arg2,
1869 (unsigned long) arg3);
1870 break;
1871 }
1872
1873 /* Just ignore this. We could make this equal to munmap,
1874 but then we'd have to make sure no anon mmaps gets this
1875 address before a subsequent MAP_FIXED mmap intended to
1876 override it. */
1877 retval = 0;
1878 break;
1879 }
1880
1881 case TARGET_SYS_ioctl:
1882 {
1883 /* We support only a very limited functionality: checking
1884 stdout with TCGETS to perform the isatty function. The
1885 TCGETS ioctl isn't actually performed or the result used by
1886 an isatty () caller in a "hello, world" program; only the
1887 return value is then used. Maybe we shouldn't care about
1888 the environment of the simulator regarding isatty, but
1889 that's been working before, in the xsim simulator. */
1890 if (arg2 == TARGET_TCGETS && arg1 == 1)
1891 retval = isatty (1) ? 0 : cb_host_to_target_errno (cb, EINVAL);
1892 else
1893 retval = -cb_host_to_target_errno (cb, EINVAL);
1894 break;
1895 }
1896
1897 case TARGET_SYS_munmap:
1898 {
1899 USI addr = arg1;
1900 USI len = arg2;
1901 USI result
1902 = unmap_pages (sd, &current_cpu->highest_mmapped_page, addr,
1903 len);
1904 retval = result != 0 ? -cb_host_to_target_errno (cb, result) : 0;
1905 break;
1906 }
1907
1908 case TARGET_SYS_wait4:
1909 {
1910 int i;
1911 USI pid = arg1;
1912 USI saddr = arg2;
1913 USI options = arg3;
1914 USI rusagep = arg4;
1915
1916 /* FIXME: We're not properly implementing __WCLONE, and we
1917 don't really need the special casing so we might as well
1918 make this general. */
1919 if ((!(pid == (USI) -1
1920 && options == (TARGET___WCLONE | TARGET_WNOHANG)
1921 && saddr != 0)
1922 && !(pid > 0
1923 && (options == TARGET___WCLONE
1924 || options == TARGET___WALL)))
1925 || rusagep != 0
1926 || current_cpu->thread_data == NULL)
1927 {
1928 retval
1929 = cris_unknown_syscall (current_cpu, pc,
1930 "Unimplemented wait4 call "
1931 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1932 (unsigned long) arg1,
1933 (unsigned long) arg2,
1934 (unsigned long) arg3,
1935 (unsigned long) arg4);
1936 break;
1937 }
1938
1939 if (pid == (USI) -1)
1940 for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
1941 {
1942 if (current_cpu->thread_data[threadno].threadid
1943 == current_cpu->thread_data[i].parent_threadid
1944 && current_cpu->thread_data[i].threadid != 0
1945 && current_cpu->thread_data[i].cpu_context == NULL)
1946 {
1947 /* A zombied child. Get the exit value and clear the
1948 zombied entry so it will be reused. */
1949 sim_core_write_unaligned_4 (current_cpu, pc, 0, saddr,
1950 current_cpu
1951 ->thread_data[i].exitval);
1952 retval
1953 = current_cpu->thread_data[i].threadid + TARGET_PID;
1954 memset (&current_cpu->thread_data[i], 0,
1955 sizeof (current_cpu->thread_data[i]));
1956 goto outer_break;
1957 }
1958 }
1959 else
1960 {
1961 /* We're waiting for a specific PID. If we don't find
1962 it zombied on this run, rerun the syscall. */
1963 for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
1964 if (pid == current_cpu->thread_data[i].threadid + TARGET_PID
1965 && current_cpu->thread_data[i].cpu_context == NULL)
1966 {
1967 if (saddr != 0)
1968 /* Get the exit value if the caller wants it. */
1969 sim_core_write_unaligned_4 (current_cpu, pc, 0,
1970 saddr,
1971 current_cpu
1972 ->thread_data[i]
1973 .exitval);
1974
1975 retval
1976 = current_cpu->thread_data[i].threadid + TARGET_PID;
1977 memset (&current_cpu->thread_data[i], 0,
1978 sizeof (current_cpu->thread_data[i]));
1979
1980 goto outer_break;
1981 }
1982
1983 sim_pc_set (current_cpu, pc);
1984 }
1985
1986 retval = -cb_host_to_target_errno (cb, ECHILD);
1987 outer_break:
1988 break;
1989 }
1990
1991 case TARGET_SYS_rt_sigaction:
1992 {
1993 USI signum = arg1;
1994 USI old_sa = arg3;
1995 USI new_sa = arg2;
1996
1997 /* The kernel says:
1998 struct sigaction {
1999 __sighandler_t sa_handler;
2000 unsigned long sa_flags;
2001 void (*sa_restorer)(void);
2002 sigset_t sa_mask;
2003 }; */
2004
2005 if (old_sa != 0)
2006 {
2007 sim_core_write_unaligned_4 (current_cpu, pc, 0, old_sa + 0,
2008 current_cpu->sighandler[signum]);
2009 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 4, 0);
2010 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 8, 0);
2011
2012 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
2013 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 12, 0);
2014 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 16, 0);
2015 }
2016 if (new_sa != 0)
2017 {
2018 USI target_sa_handler
2019 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa);
2020 USI target_sa_flags
2021 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 4);
2022 USI target_sa_restorer
2023 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 8);
2024 USI target_sa_mask_low
2025 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 12);
2026 USI target_sa_mask_high
2027 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 16);
2028
2029 /* We won't interrupt a syscall so we won't restart it,
2030 but a signal(2) call ends up syscalling rt_sigaction
2031 with this flag, so we have to handle it. The
2032 sa_restorer field contains garbage when not
2033 TARGET_SA_RESTORER, so don't look at it. For the
2034 time being, we don't nest sighandlers, so we
2035 ignore the sa_mask, which simplifies things. */
2036 if ((target_sa_flags != 0
2037 && target_sa_flags != TARGET_SA_RESTART
2038 && target_sa_flags != (TARGET_SA_RESTART|TARGET_SA_SIGINFO))
2039 || target_sa_handler == 0)
2040 {
2041 retval
2042 = cris_unknown_syscall (current_cpu, pc,
2043 "Unimplemented rt_sigaction "
2044 "syscall "
2045 "(0x%lx, 0x%lx: "
2046 "[0x%x, 0x%x, 0x%x, "
2047 "{0x%x, 0x%x}], 0x%lx)\n",
2048 (unsigned long) arg1,
2049 (unsigned long) arg2,
2050 target_sa_handler,
2051 target_sa_flags,
2052 target_sa_restorer,
2053 target_sa_mask_low,
2054 target_sa_mask_high,
2055 (unsigned long) arg3);
2056 break;
2057 }
2058
2059 current_cpu->sighandler[signum] = target_sa_handler;
2060
2061 /* Because we may have unblocked signals, one may now be
2062 pending, if there are threads, that is. */
2063 if (current_cpu->thread_data)
2064 current_cpu->thread_data[threadno].sigpending = 1;
2065 }
2066 retval = 0;
2067 break;
2068 }
2069
2070 case TARGET_SYS_mremap:
2071 {
2072 USI addr = arg1;
2073 USI old_len = arg2;
2074 USI new_len = arg3;
2075 USI flags = arg4;
2076 USI new_addr = arg5;
2077 USI mapped_addr;
2078
2079 if (new_len == old_len)
2080 /* The program and/or library is possibly confused but
2081 this is a valid call. Happens with ipps-1.40 on file
2082 svs_all. */
2083 retval = addr;
2084 else if (new_len < old_len)
2085 {
2086 /* Shrinking is easy. */
2087 if (unmap_pages (sd, &current_cpu->highest_mmapped_page,
2088 addr + new_len, old_len - new_len) != 0)
2089 retval = -cb_host_to_target_errno (cb, EINVAL);
2090 else
2091 retval = addr;
2092 }
2093 else if (! is_mapped (sd, &current_cpu->highest_mmapped_page,
2094 addr + old_len, new_len - old_len))
2095 {
2096 /* If the extension isn't mapped, we can just add it. */
2097 mapped_addr
2098 = create_map (sd, &current_cpu->highest_mmapped_page,
2099 addr + old_len, new_len - old_len);
2100
2101 if (mapped_addr > (USI) -8192)
2102 retval = -cb_host_to_target_errno (cb, -(SI) mapped_addr);
2103 else
2104 retval = addr;
2105 }
2106 else if (flags & TARGET_MREMAP_MAYMOVE)
2107 {
2108 /* Create a whole new map and copy the contents
2109 block-by-block there. We ignore the new_addr argument
2110 for now. */
2111 char buf[8192];
2112 USI prev_addr = addr;
2113 USI prev_len = old_len;
2114
2115 mapped_addr
2116 = create_map (sd, &current_cpu->highest_mmapped_page,
2117 0, new_len);
2118
2119 if (mapped_addr > (USI) -8192)
2120 {
2121 retval = -cb_host_to_target_errno (cb, -(SI) new_addr);
2122 break;
2123 }
2124
2125 retval = mapped_addr;
2126
2127 for (; old_len > 0;
2128 old_len -= 8192, mapped_addr += 8192, addr += 8192)
2129 {
2130 if (sim_core_read_buffer (sd, current_cpu, read_map, buf,
2131 addr, 8192) != 8192
2132 || sim_core_write_buffer (sd, current_cpu, 0, buf,
2133 mapped_addr, 8192) != 8192)
2134 abort ();
2135 }
2136
2137 if (unmap_pages (sd, &current_cpu->highest_mmapped_page,
2138 prev_addr, prev_len) != 0)
2139 abort ();
2140 }
2141 else
2142 retval = -cb_host_to_target_errno (cb, -ENOMEM);
2143 break;
2144 }
2145
2146 case TARGET_SYS_poll:
2147 {
2148 int npollfds = arg2;
2149 int timeout = arg3;
2150 SI ufds = arg1;
2151 SI fd = -1;
2152 HI events = -1;
2153 HI revents = 0;
2154 struct stat buf;
2155 int i;
2156
2157 /* The kernel says:
2158 struct pollfd {
2159 int fd;
2160 short events;
2161 short revents;
2162 }; */
2163
2164 /* Check that this is the expected poll call from
2165 linuxthreads/manager.c; we don't support anything else.
2166 Remember, fd == 0 isn't supported. */
2167 if (npollfds != 1
2168 || ((fd = sim_core_read_unaligned_4 (current_cpu, pc,
2169 0, ufds)) <= 0)
2170 || ((events = sim_core_read_unaligned_2 (current_cpu, pc,
2171 0, ufds + 4))
2172 != TARGET_POLLIN)
2173 || ((cb->fstat) (cb, fd, &buf) != 0
2174 || (buf.st_mode & S_IFIFO) == 0)
2175 || current_cpu->thread_data == NULL)
2176 {
2177 retval
2178 = cris_unknown_syscall (current_cpu, pc,
2179 "Unimplemented poll syscall "
2180 "(0x%lx: [0x%x, 0x%x, x], "
2181 "0x%lx, 0x%lx)\n",
2182 (unsigned long) arg1, fd, events,
2183 (unsigned long) arg2,
2184 (unsigned long) arg3);
2185 break;
2186 }
2187
2188 retval = 0;
2189
2190 /* Iterate over threads; find a marker that a writer is
2191 sleeping, waiting for a reader. */
2192 for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
2193 if (current_cpu->thread_data[i].cpu_context != NULL
2194 && current_cpu->thread_data[i].pipe_read_fd == fd)
2195 {
2196 revents = TARGET_POLLIN;
2197 retval = 1;
2198 break;
2199 }
2200
2201 /* Timeout decreases with whatever time passed between the
2202 last syscall and this. That's not exactly right for the
2203 first call, but it's close enough that it isn't
2204 worthwhile to complicate matters by making that a special
2205 case. */
2206 timeout
2207 -= (TARGET_TIME_MS (current_cpu)
2208 - (current_cpu->thread_data[threadno].last_execution));
2209
2210 /* Arrange to repeat this syscall until timeout or event,
2211 decreasing timeout at each iteration. */
2212 if (timeout > 0 && revents == 0)
2213 {
2214 bfd_byte timeout_buf[4];
2215
2216 bfd_putl32 (timeout, timeout_buf);
2217 (*CPU_REG_STORE (current_cpu)) (current_cpu,
2218 H_GR_R12, timeout_buf, 4);
2219 sim_pc_set (current_cpu, pc);
2220 retval = arg1;
2221 break;
2222 }
2223
2224 sim_core_write_unaligned_2 (current_cpu, pc, 0, ufds + 4 + 2,
2225 revents);
2226 break;
2227 }
2228
2229 case TARGET_SYS_time:
2230 {
2231 retval = (int) (*cb->time) (cb, 0L);
2232
2233 /* At time of this writing, CB_SYSCALL_time doesn't do the
2234 part of setting *arg1 to the return value. */
2235 if (arg1)
2236 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, retval);
2237 break;
2238 }
2239
2240 case TARGET_SYS_gettimeofday:
2241 if (arg1 != 0)
2242 {
2243 USI ts = TARGET_TIME (current_cpu);
2244 USI tms = TARGET_TIME_MS (current_cpu);
2245
2246 /* First dword is seconds since TARGET_EPOCH. */
2247 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, ts);
2248
2249 /* Second dword is microseconds. */
2250 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1 + 4,
2251 (tms % 1000) * 1000);
2252 }
2253 if (arg2 != 0)
2254 {
2255 /* Time-zone info is always cleared. */
2256 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, 0);
2257 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, 0);
2258 }
2259 retval = 0;
2260 break;
2261
2262 case TARGET_SYS_llseek:
2263 {
2264 /* If it fits, tweak parameters to fit the "generic" 32-bit
2265 lseek and use that. */
2266 SI fd = arg1;
2267 SI offs_hi = arg2;
2268 SI offs_lo = arg3;
2269 SI resultp = arg4;
2270 SI whence = arg5;
2271 retval = 0;
2272
2273 if (!((offs_hi == 0 && offs_lo >= 0)
2274 || (offs_hi == -1 && offs_lo < 0)))
2275 {
2276 retval
2277 = cris_unknown_syscall (current_cpu, pc,
2278 "Unimplemented llseek offset,"
2279 " fd %d: 0x%x:0x%x\n",
2280 fd, (unsigned) arg2,
2281 (unsigned) arg3);
2282 break;
2283 }
2284
2285 s.func = TARGET_SYS_lseek;
2286 s.arg2 = offs_lo;
2287 s.arg3 = whence;
2288 if (cb_syscall (cb, &s) != CB_RC_OK)
2289 {
2290 sim_io_eprintf (sd, "Break 13: invalid %d? Returned %ld\n", callnum,
2291 s.result);
2292 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
2293 }
2294 if (s.result < 0)
2295 retval = -s.errcode;
2296 else
2297 {
2298 sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp,
2299 s.result);
2300 sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp + 4,
2301 s.result < 0 ? -1 : 0);
2302 }
2303 break;
2304 }
2305
2306 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2307 where:
2308 struct iovec {
2309 void *iov_base; Starting address
2310 size_t iov_len; Number of bytes to transfer
2311 }; */
2312 case TARGET_SYS_writev:
2313 {
2314 SI fd = arg1;
2315 SI iov = arg2;
2316 SI iovcnt = arg3;
2317 SI retcnt = 0;
2318 int i;
2319
2320 /* We'll ignore strict error-handling and just do multiple write calls. */
2321 for (i = 0; i < iovcnt; i++)
2322 {
2323 int sysret;
2324 USI iov_base
2325 = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2326 iov + 8*i);
2327 USI iov_len
2328 = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2329 iov + 8*i + 4);
2330
2331 s.func = TARGET_SYS_write;
2332 s.arg1 = fd;
2333 s.arg2 = iov_base;
2334 s.arg3 = iov_len;
2335
2336 if (cb_syscall (cb, &s) != CB_RC_OK)
2337 abort ();
2338 sysret = s.result == -1 ? -s.errcode : s.result;
2339
2340 if (sysret != iov_len)
2341 {
2342 if (i != 0)
2343 abort ();
2344 retcnt = sysret;
2345 break;
2346 }
2347
2348 retcnt += iov_len;
2349 }
2350
2351 retval = retcnt;
2352 }
2353 break;
2354
2355 /* This one does have a generic callback function, but at the time
2356 of this writing, cb_syscall does not have code for it, and we
2357 need target-specific code for the threads implementation
2358 anyway. */
2359 case TARGET_SYS_kill:
2360 {
2361 USI pid = arg1;
2362 USI sig = arg2;
2363
2364 retval = 0;
2365
2366 /* At kill(2), glibc sets signal masks such that the thread
2367 machinery is initialized. Still, there is and was only
2368 one thread. */
2369 if (current_cpu->max_threadid == 0)
2370 {
2371 if (pid != TARGET_PID)
2372 {
2373 retval = -cb_host_to_target_errno (cb, EPERM);
2374 break;
2375 }
2376
2377 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2378 if (sig == TARGET_SIGABRT)
2379 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2380 the end-point for failing GCC test-cases. */
2381 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2382 SIM_SIGABRT);
2383 else
2384 {
2385 sim_io_eprintf (sd, "Unimplemented signal: %d\n", sig);
2386 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2387 SIM_SIGILL);
2388 }
2389
2390 /* This will not be reached. */
2391 abort ();
2392 }
2393 else
2394 retval = deliver_signal (current_cpu, sig, pid);
2395 break;
2396 }
2397
2398 case TARGET_SYS_rt_sigprocmask:
2399 {
2400 int i;
2401 USI how = arg1;
2402 USI newsetp = arg2;
2403 USI oldsetp = arg3;
2404
2405 if (how != TARGET_SIG_BLOCK
2406 && how != TARGET_SIG_SETMASK
2407 && how != TARGET_SIG_UNBLOCK)
2408 {
2409 retval
2410 = cris_unknown_syscall (current_cpu, pc,
2411 "Unimplemented rt_sigprocmask "
2412 "syscall (0x%x, 0x%x, 0x%x)\n",
2413 arg1, arg2, arg3);
2414 break;
2415 }
2416
2417 if (newsetp)
2418 {
2419 USI set_low
2420 = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2421 newsetp);
2422 USI set_high
2423 = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2424 newsetp + 4);
2425
2426 /* The sigmask is kept in the per-thread data, so we may
2427 need to create the first one. */
2428 if (current_cpu->thread_data == NULL)
2429 make_first_thread (current_cpu);
2430
2431 if (how == TARGET_SIG_SETMASK)
2432 for (i = 0; i < 64; i++)
2433 current_cpu->thread_data[threadno].sigdata[i].blocked = 0;
2434
2435 for (i = 0; i < 32; i++)
2436 if ((set_low & (1 << i)))
2437 current_cpu->thread_data[threadno].sigdata[i + 1].blocked
2438 = (how != TARGET_SIG_UNBLOCK);
2439
2440 for (i = 0; i < 31; i++)
2441 if ((set_high & (1 << i)))
2442 current_cpu->thread_data[threadno].sigdata[i + 33].blocked
2443 = (how != TARGET_SIG_UNBLOCK);
2444
2445 /* The mask changed, so a signal may be unblocked for
2446 execution. */
2447 current_cpu->thread_data[threadno].sigpending = 1;
2448 }
2449
2450 if (oldsetp != 0)
2451 {
2452 USI set_low = 0;
2453 USI set_high = 0;
2454
2455 for (i = 0; i < 32; i++)
2456 if (current_cpu->thread_data[threadno]
2457 .sigdata[i + 1].blocked)
2458 set_low |= 1 << i;
2459 for (i = 0; i < 31; i++)
2460 if (current_cpu->thread_data[threadno]
2461 .sigdata[i + 33].blocked)
2462 set_high |= 1 << i;
2463
2464 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 0, set_low);
2465 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 4, set_high);
2466 }
2467
2468 retval = 0;
2469 break;
2470 }
2471
2472 case TARGET_SYS_sigreturn:
2473 {
2474 int i;
2475 bfd_byte regbuf[4];
2476 int was_sigsuspended;
2477
2478 if (current_cpu->thread_data == NULL
2479 /* The CPU context is saved with the simulator data, not
2480 on the stack as in the real world. */
2481 || (current_cpu->thread_data[threadno].cpu_context_atsignal
2482 == NULL))
2483 {
2484 retval
2485 = cris_unknown_syscall (current_cpu, pc,
2486 "Invalid sigreturn syscall: "
2487 "no signal handler active "
2488 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2489 "0x%lx, 0x%lx)\n",
2490 (unsigned long) arg1,
2491 (unsigned long) arg2,
2492 (unsigned long) arg3,
2493 (unsigned long) arg4,
2494 (unsigned long) arg5,
2495 (unsigned long) arg6);
2496 break;
2497 }
2498
2499 was_sigsuspended
2500 = current_cpu->thread_data[threadno].sigsuspended;
2501
2502 /* Restore the sigmask, either from the stack copy made when
2503 the sighandler was called, or from the saved state
2504 specifically for sigsuspend(2). */
2505 if (was_sigsuspended)
2506 {
2507 current_cpu->thread_data[threadno].sigsuspended = 0;
2508 for (i = 0; i < 64; i++)
2509 current_cpu->thread_data[threadno].sigdata[i].blocked
2510 = current_cpu->thread_data[threadno]
2511 .sigdata[i].blocked_suspendsave;
2512 }
2513 else
2514 {
2515 USI sp;
2516 USI set_low;
2517 USI set_high;
2518
2519 (*CPU_REG_FETCH (current_cpu)) (current_cpu,
2520 H_GR_SP, regbuf, 4);
2521 sp = bfd_getl32 (regbuf);
2522 set_low
2523 = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp);
2524 set_high
2525 = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp + 4);
2526
2527 for (i = 0; i < 32; i++)
2528 current_cpu->thread_data[threadno].sigdata[i + 1].blocked
2529 = (set_low & (1 << i)) != 0;
2530 for (i = 0; i < 31; i++)
2531 current_cpu->thread_data[threadno].sigdata[i + 33].blocked
2532 = (set_high & (1 << i)) != 0;
2533 }
2534
2535 /* The mask changed, so a signal may be unblocked for
2536 execution. */
2537 current_cpu->thread_data[threadno].sigpending = 1;
2538
2539 memcpy (&current_cpu->cpu_data_placeholder,
2540 current_cpu->thread_data[threadno].cpu_context_atsignal,
2541 current_cpu->thread_cpu_data_size);
2542 free (current_cpu->thread_data[threadno].cpu_context_atsignal);
2543 current_cpu->thread_data[threadno].cpu_context_atsignal = NULL;
2544
2545 /* The return value must come from the saved R10. */
2546 (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, regbuf, 4);
2547 retval = bfd_getl32 (regbuf);
2548
2549 /* We must also break the "sigsuspension loop". */
2550 if (was_sigsuspended)
2551 sim_pc_set (current_cpu, sim_pc_get (current_cpu) + 2);
2552 break;
2553 }
2554
2555 case TARGET_SYS_rt_sigsuspend:
2556 {
2557 USI newsetp = arg1;
2558 USI setsize = arg2;
2559
2560 if (setsize != 8)
2561 {
2562 retval
2563 = cris_unknown_syscall (current_cpu, pc,
2564 "Unimplemented rt_sigsuspend syscall"
2565 " arguments (0x%lx, 0x%lx)\n",
2566 (unsigned long) arg1,
2567 (unsigned long) arg2);
2568 break;
2569 }
2570
2571 /* Don't change the signal mask if we're already in
2572 sigsuspend state (i.e. this syscall is a rerun). */
2573 else if (!current_cpu->thread_data[threadno].sigsuspended)
2574 {
2575 USI set_low
2576 = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2577 newsetp);
2578 USI set_high
2579 = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2580 newsetp + 4);
2581 int i;
2582
2583 /* Save the current sigmask and insert the user-supplied
2584 one. */
2585 for (i = 0; i < 32; i++)
2586 {
2587 current_cpu->thread_data[threadno]
2588 .sigdata[i + 1].blocked_suspendsave
2589 = current_cpu->thread_data[threadno]
2590 .sigdata[i + 1].blocked;
2591
2592 current_cpu->thread_data[threadno]
2593 .sigdata[i + 1].blocked = (set_low & (1 << i)) != 0;
2594 }
2595 for (i = 0; i < 31; i++)
2596 {
2597 current_cpu->thread_data[threadno]
2598 .sigdata[i + 33].blocked_suspendsave
2599 = current_cpu->thread_data[threadno]
2600 .sigdata[i + 33].blocked;
2601 current_cpu->thread_data[threadno]
2602 .sigdata[i + 33].blocked = (set_high & (1 << i)) != 0;
2603 }
2604
2605 current_cpu->thread_data[threadno].sigsuspended = 1;
2606
2607 /* The mask changed, so a signal may be unblocked for
2608 execution. */
2609 current_cpu->thread_data[threadno].sigpending = 1;
2610 }
2611
2612 /* Because we don't use arg1 (newsetp) when this syscall is
2613 rerun, it doesn't matter that we overwrite it with the
2614 (constant) return value. */
2615 retval = -cb_host_to_target_errno (cb, EINTR);
2616 sim_pc_set (current_cpu, pc);
2617 break;
2618 }
2619
2620 /* Add case labels here for other syscalls using the 32-bit
2621 "struct stat", provided they have a corresponding simulator
2622 function of course. */
2623 case TARGET_SYS_stat:
2624 case TARGET_SYS_fstat:
2625 {
2626 /* As long as the infrastructure doesn't cache anything
2627 related to the stat mapping, this trick gets us a dual
2628 "struct stat"-type mapping in the least error-prone way. */
2629 const char *saved_map = cb->stat_map;
2630 CB_TARGET_DEFS_MAP *saved_syscall_map = cb->syscall_map;
2631
2632 cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_stat32_map;
2633 cb->stat_map = stat32_map;
2634
2635 if (cb_syscall (cb, &s) != CB_RC_OK)
2636 {
2637 abort ();
2638 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2639 SIM_SIGILL);
2640 }
2641 retval = s.result == -1 ? -s.errcode : s.result;
2642
2643 cb->stat_map = saved_map;
2644 cb->syscall_map = saved_syscall_map;
2645 break;
2646 }
2647
2648 case TARGET_SYS_getcwd:
2649 {
2650 USI buf = arg1;
2651 USI size = arg2;
2652
2653 char *cwd = xmalloc (SIM_PATHMAX);
2654 if (cwd != getcwd (cwd, SIM_PATHMAX))
2655 abort ();
2656
2657 /* FIXME: When and if we support chdir, we need something
2658 a bit more elaborate. */
2659 if (simulator_sysroot[0] != '\0')
2660 strcpy (cwd, "/");
2661
2662 retval = -cb_host_to_target_errno (cb, ERANGE);
2663 if (strlen (cwd) + 1 <= size)
2664 {
2665 retval = strlen (cwd) + 1;
2666 if (sim_core_write_buffer (sd, current_cpu, 0, cwd,
2667 buf, retval)
2668 != (unsigned int) retval)
2669 retval = -cb_host_to_target_errno (cb, EFAULT);
2670 }
2671 free (cwd);
2672 break;
2673 }
2674
2675 case TARGET_SYS_access:
2676 {
2677 SI path = arg1;
2678 SI mode = arg2;
2679 char *pbuf = xmalloc (SIM_PATHMAX);
2680 int i;
2681 int o = 0;
2682 int hmode = 0;
2683
2684 if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/')
2685 {
2686 strcpy (pbuf, simulator_sysroot);
2687 o += strlen (simulator_sysroot);
2688 }
2689
2690 for (i = 0; i + o < SIM_PATHMAX; i++)
2691 {
2692 pbuf[i + o]
2693 = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i);
2694 if (pbuf[i + o] == 0)
2695 break;
2696 }
2697
2698 if (i + o == SIM_PATHMAX)
2699 {
2700 retval = -cb_host_to_target_errno (cb, ENAMETOOLONG);
2701 break;
2702 }
2703
2704 /* Assert that we don't get calls for files for which we
2705 don't have support. */
2706 if (strncmp (pbuf + strlen (simulator_sysroot),
2707 "/proc/", 6) == 0)
2708 abort ();
2709 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2710 X_AFLAG (R_OK);
2711 X_AFLAG (W_OK);
2712 X_AFLAG (X_OK);
2713 X_AFLAG (F_OK);
2714 #undef X_AFLAG
2715
2716 if (access (pbuf, hmode) != 0)
2717 retval = -cb_host_to_target_errno (cb, errno);
2718 else
2719 retval = 0;
2720
2721 free (pbuf);
2722 break;
2723 }
2724
2725 case TARGET_SYS_readlink:
2726 {
2727 SI path = arg1;
2728 SI buf = arg2;
2729 SI bufsiz = arg3;
2730 char *pbuf = xmalloc (SIM_PATHMAX);
2731 char *lbuf = xmalloc (SIM_PATHMAX);
2732 char *lbuf_alloc = lbuf;
2733 int nchars = -1;
2734 int i;
2735 int o = 0;
2736
2737 if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/')
2738 {
2739 strcpy (pbuf, simulator_sysroot);
2740 o += strlen (simulator_sysroot);
2741 }
2742
2743 for (i = 0; i + o < SIM_PATHMAX; i++)
2744 {
2745 pbuf[i + o]
2746 = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i);
2747 if (pbuf[i + o] == 0)
2748 break;
2749 }
2750
2751 if (i + o == SIM_PATHMAX)
2752 {
2753 retval = -cb_host_to_target_errno (cb, ENAMETOOLONG);
2754 break;
2755 }
2756
2757 /* Intervene calls for certain files expected in the target
2758 proc file system. */
2759 if (strcmp (pbuf + strlen (simulator_sysroot),
2760 "/proc/" XSTRING (TARGET_PID) "/exe") == 0)
2761 {
2762 char *argv0
2763 = (STATE_PROG_ARGV (sd) != NULL
2764 ? *STATE_PROG_ARGV (sd) : NULL);
2765
2766 if (argv0 == NULL || *argv0 == '.')
2767 {
2768 retval
2769 = cris_unknown_syscall (current_cpu, pc,
2770 "Unimplemented readlink syscall "
2771 "(0x%lx: [\"%s\"], 0x%lx)\n",
2772 (unsigned long) arg1, pbuf,
2773 (unsigned long) arg2);
2774 break;
2775 }
2776 else if (*argv0 == '/')
2777 {
2778 if (strncmp (simulator_sysroot, argv0,
2779 strlen (simulator_sysroot)) == 0)
2780 argv0 += strlen (simulator_sysroot);
2781
2782 strcpy (lbuf, argv0);
2783 nchars = strlen (argv0) + 1;
2784 }
2785 else
2786 {
2787 if (getcwd (lbuf, SIM_PATHMAX) != NULL
2788 && strlen (lbuf) + 2 + strlen (argv0) < SIM_PATHMAX)
2789 {
2790 if (strncmp (simulator_sysroot, lbuf,
2791 strlen (simulator_sysroot)) == 0)
2792 lbuf += strlen (simulator_sysroot);
2793
2794 strcat (lbuf, "/");
2795 strcat (lbuf, argv0);
2796 nchars = strlen (lbuf) + 1;
2797 }
2798 else
2799 abort ();
2800 }
2801 }
2802 else
2803 nchars = readlink (pbuf, lbuf, SIM_PATHMAX);
2804
2805 /* We trust that the readlink result returns a *relative*
2806 link, or one already adjusted for the file-path-prefix.
2807 (We can't generally tell the difference, so we go with
2808 the easiest decision; no adjustment.) */
2809
2810 if (nchars == -1)
2811 {
2812 retval = -cb_host_to_target_errno (cb, errno);
2813 break;
2814 }
2815
2816 if (bufsiz < nchars)
2817 nchars = bufsiz;
2818
2819 if (sim_core_write_buffer (sd, current_cpu, write_map, lbuf,
2820 buf, nchars) != (unsigned int) nchars)
2821 retval = -cb_host_to_target_errno (cb, EFAULT);
2822 else
2823 retval = nchars;
2824
2825 free (pbuf);
2826 free (lbuf_alloc);
2827 break;
2828 }
2829
2830 case TARGET_SYS_sched_getscheduler:
2831 {
2832 USI pid = arg1;
2833
2834 /* FIXME: Search (other) existing threads. */
2835 if (pid != 0 && pid != TARGET_PID)
2836 retval = -cb_host_to_target_errno (cb, ESRCH);
2837 else
2838 retval = TARGET_SCHED_OTHER;
2839 break;
2840 }
2841
2842 case TARGET_SYS_sched_getparam:
2843 {
2844 USI pid = arg1;
2845 USI paramp = arg2;
2846
2847 /* The kernel says:
2848 struct sched_param {
2849 int sched_priority;
2850 }; */
2851
2852 if (pid != 0 && pid != TARGET_PID)
2853 retval = -cb_host_to_target_errno (cb, ESRCH);
2854 else
2855 {
2856 /* FIXME: Save scheduler setting before threads are
2857 created too. */
2858 sim_core_write_unaligned_4 (current_cpu, pc, 0, paramp,
2859 current_cpu->thread_data != NULL
2860 ? (current_cpu
2861 ->thread_data[threadno]
2862 .priority)
2863 : 0);
2864 retval = 0;
2865 }
2866 break;
2867 }
2868
2869 case TARGET_SYS_sched_setparam:
2870 {
2871 USI pid = arg1;
2872 USI paramp = arg2;
2873
2874 if ((pid != 0 && pid != TARGET_PID)
2875 || sim_core_read_unaligned_4 (current_cpu, pc, 0,
2876 paramp) != 0)
2877 retval = -cb_host_to_target_errno (cb, EINVAL);
2878 else
2879 retval = 0;
2880 break;
2881 }
2882
2883 case TARGET_SYS_sched_setscheduler:
2884 {
2885 USI pid = arg1;
2886 USI policy = arg2;
2887 USI paramp = arg3;
2888
2889 if ((pid != 0 && pid != TARGET_PID)
2890 || policy != TARGET_SCHED_OTHER
2891 || sim_core_read_unaligned_4 (current_cpu, pc, 0,
2892 paramp) != 0)
2893 retval = -cb_host_to_target_errno (cb, EINVAL);
2894 else
2895 /* FIXME: Save scheduler setting to be read in later
2896 sched_getparam calls. */
2897 retval = 0;
2898 break;
2899 }
2900
2901 case TARGET_SYS_sched_yield:
2902 /* We reschedule to the next thread after a syscall anyway, so
2903 we don't have to do anything here than to set the return
2904 value. */
2905 retval = 0;
2906 break;
2907
2908 case TARGET_SYS_sched_get_priority_min:
2909 case TARGET_SYS_sched_get_priority_max:
2910 if (arg1 != 0)
2911 retval = -cb_host_to_target_errno (cb, EINVAL);
2912 else
2913 retval = 0;
2914 break;
2915
2916 case TARGET_SYS_ugetrlimit:
2917 {
2918 unsigned int curlim, maxlim;
2919 if (arg1 != TARGET_RLIMIT_STACK && arg1 != TARGET_RLIMIT_NOFILE)
2920 {
2921 retval = -cb_host_to_target_errno (cb, EINVAL);
2922 break;
2923 }
2924
2925 /* The kernel says:
2926 struct rlimit {
2927 unsigned long rlim_cur;
2928 unsigned long rlim_max;
2929 }; */
2930 if (arg1 == TARGET_RLIMIT_NOFILE)
2931 {
2932 /* Sadly a very low limit. Better not lie, though. */
2933 maxlim = curlim = MAX_CALLBACK_FDS;
2934 }
2935 else /* arg1 == TARGET_RLIMIT_STACK */
2936 {
2937 maxlim = 0xffffffff;
2938 curlim = 0x800000;
2939 }
2940 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, curlim);
2941 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, maxlim);
2942 retval = 0;
2943 break;
2944 }
2945
2946 case TARGET_SYS_setrlimit:
2947 if (arg1 != TARGET_RLIMIT_STACK)
2948 {
2949 retval = -cb_host_to_target_errno (cb, EINVAL);
2950 break;
2951 }
2952 /* FIXME: Save values for future ugetrlimit calls. */
2953 retval = 0;
2954 break;
2955
2956 /* Provide a very limited subset of the sysctl functions, and
2957 abort for the rest. */
2958 case TARGET_SYS__sysctl:
2959 {
2960 /* The kernel says:
2961 struct __sysctl_args {
2962 int *name;
2963 int nlen;
2964 void *oldval;
2965 size_t *oldlenp;
2966 void *newval;
2967 size_t newlen;
2968 unsigned long __unused[4];
2969 }; */
2970 SI name = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1);
2971 SI name0 = name == 0
2972 ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name);
2973 SI name1 = name == 0
2974 ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name + 4);
2975 SI nlen
2976 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 4);
2977 SI oldval
2978 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 8);
2979 SI oldlenp
2980 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 12);
2981 SI oldlen = oldlenp == 0
2982 ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, oldlenp);
2983 SI newval
2984 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 16);
2985 SI newlen
2986 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 20);
2987
2988 if (name0 == TARGET_CTL_KERN && name1 == TARGET_CTL_KERN_VERSION)
2989 {
2990 SI to_write = oldlen < (SI) sizeof (TARGET_UTSNAME)
2991 ? oldlen : (SI) sizeof (TARGET_UTSNAME);
2992
2993 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldlenp,
2994 sizeof (TARGET_UTSNAME));
2995
2996 if (sim_core_write_buffer (sd, current_cpu, write_map,
2997 TARGET_UTSNAME, oldval,
2998 to_write)
2999 != (unsigned int) to_write)
3000 retval = -cb_host_to_target_errno (cb, EFAULT);
3001 else
3002 retval = 0;
3003 break;
3004 }
3005
3006 retval
3007 = cris_unknown_syscall (current_cpu, pc,
3008 "Unimplemented _sysctl syscall "
3009 "(0x%lx: [0x%lx, 0x%lx],"
3010 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
3011 (unsigned long) name,
3012 (unsigned long) name0,
3013 (unsigned long) name1,
3014 (unsigned long) nlen,
3015 (unsigned long) oldval,
3016 (unsigned long) oldlenp,
3017 (unsigned long) newval,
3018 (unsigned long) newlen);
3019 break;
3020 }
3021
3022 case TARGET_SYS_exit:
3023 {
3024 /* Here for all but the last thread. */
3025 int i;
3026 int pid
3027 = current_cpu->thread_data[threadno].threadid + TARGET_PID;
3028 int ppid
3029 = (current_cpu->thread_data[threadno].parent_threadid
3030 + TARGET_PID);
3031 int exitsig = current_cpu->thread_data[threadno].exitsig;
3032
3033 /* Any children are now all orphans. */
3034 for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
3035 if (current_cpu->thread_data[i].parent_threadid
3036 == current_cpu->thread_data[threadno].threadid)
3037 /* Make getppid(2) return 1 for them, poor little ones. */
3038 current_cpu->thread_data[i].parent_threadid = -TARGET_PID + 1;
3039
3040 /* Free the cpu context data. When the parent has received
3041 the exit status, we'll clear the entry too. */
3042 free (current_cpu->thread_data[threadno].cpu_context);
3043 current_cpu->thread_data[threadno].cpu_context = NULL;
3044 current_cpu->m1threads--;
3045 if (arg1 != 0)
3046 {
3047 sim_io_eprintf (sd, "Thread %d exited with status %d\n",
3048 pid, arg1);
3049 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
3050 SIM_SIGILL);
3051 }
3052
3053 /* Still, we may want to support non-zero exit values. */
3054 current_cpu->thread_data[threadno].exitval = arg1 << 8;
3055
3056 if (exitsig)
3057 deliver_signal (current_cpu, exitsig, ppid);
3058 break;
3059 }
3060
3061 case TARGET_SYS_clone:
3062 {
3063 int nthreads = current_cpu->m1threads + 1;
3064 void *thread_cpu_data;
3065 bfd_byte old_sp_buf[4];
3066 bfd_byte sp_buf[4];
3067 const bfd_byte zeros[4] = { 0, 0, 0, 0 };
3068 int i;
3069
3070 /* That's right, the syscall clone arguments are reversed
3071 compared to sys_clone notes in clone(2) and compared to
3072 other Linux ports (i.e. it's the same order as in the
3073 clone(2) libcall). */
3074 USI flags = arg2;
3075 USI newsp = arg1;
3076
3077 if (nthreads == SIM_TARGET_MAX_THREADS)
3078 {
3079 retval = -cb_host_to_target_errno (cb, EAGAIN);
3080 break;
3081 }
3082
3083 /* FIXME: Implement the low byte. */
3084 if ((flags & ~TARGET_CSIGNAL) !=
3085 (TARGET_CLONE_VM
3086 | TARGET_CLONE_FS
3087 | TARGET_CLONE_FILES
3088 | TARGET_CLONE_SIGHAND)
3089 || newsp == 0)
3090 {
3091 retval
3092 = cris_unknown_syscall (current_cpu, pc,
3093 "Unimplemented clone syscall "
3094 "(0x%lx, 0x%lx)\n",
3095 (unsigned long) arg1,
3096 (unsigned long) arg2);
3097 break;
3098 }
3099
3100 if (current_cpu->thread_data == NULL)
3101 make_first_thread (current_cpu);
3102
3103 /* The created thread will get the new SP and a cleared R10.
3104 Since it's created out of a copy of the old thread and we
3105 don't have a set-register-function that just take the
3106 cpu_data as a parameter, we set the childs values first,
3107 and write back or overwrite them in the parent after the
3108 copy. */
3109 (*CPU_REG_FETCH (current_cpu)) (current_cpu,
3110 H_GR_SP, old_sp_buf, 4);
3111 bfd_putl32 (newsp, sp_buf);
3112 (*CPU_REG_STORE (current_cpu)) (current_cpu,
3113 H_GR_SP, sp_buf, 4);
3114 (*CPU_REG_STORE (current_cpu)) (current_cpu,
3115 H_GR_R10, (bfd_byte *) zeros, 4);
3116 thread_cpu_data
3117 = (*current_cpu
3118 ->make_thread_cpu_data) (current_cpu,
3119 &current_cpu->cpu_data_placeholder);
3120 (*CPU_REG_STORE (current_cpu)) (current_cpu,
3121 H_GR_SP, old_sp_buf, 4);
3122
3123 retval = ++current_cpu->max_threadid + TARGET_PID;
3124
3125 /* Find an unused slot. After a few threads have been created
3126 and exited, the array is expected to be a bit fragmented.
3127 We don't reuse the first entry, though, that of the
3128 original thread. */
3129 for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
3130 if (current_cpu->thread_data[i].cpu_context == NULL
3131 /* Don't reuse a zombied entry. */
3132 && current_cpu->thread_data[i].threadid == 0)
3133 break;
3134
3135 memcpy (&current_cpu->thread_data[i],
3136 &current_cpu->thread_data[threadno],
3137 sizeof (current_cpu->thread_data[i]));
3138 current_cpu->thread_data[i].cpu_context = thread_cpu_data;
3139 current_cpu->thread_data[i].cpu_context_atsignal = NULL;
3140 current_cpu->thread_data[i].threadid = current_cpu->max_threadid;
3141 current_cpu->thread_data[i].parent_threadid
3142 = current_cpu->thread_data[threadno].threadid;
3143 current_cpu->thread_data[i].pipe_read_fd = 0;
3144 current_cpu->thread_data[i].pipe_write_fd = 0;
3145 current_cpu->thread_data[i].at_syscall = 0;
3146 current_cpu->thread_data[i].sigpending = 0;
3147 current_cpu->thread_data[i].sigsuspended = 0;
3148 current_cpu->thread_data[i].exitsig = flags & TARGET_CSIGNAL;
3149 current_cpu->m1threads = nthreads;
3150 break;
3151 }
3152
3153 /* Better watch these in case they do something necessary. */
3154 case TARGET_SYS_socketcall:
3155 retval = -cb_host_to_target_errno (cb, ENOSYS);
3156 break;
3157
3158 case TARGET_SYS_set_thread_area:
3159 /* Do the same error check as Linux. */
3160 if (arg1 & 255)
3161 {
3162 retval = -cb_host_to_target_errno (cb, EINVAL);
3163 break;
3164 }
3165 (*current_cpu->set_target_thread_data) (current_cpu, arg1);
3166 retval = 0;
3167 break;
3168
3169 unimplemented_syscall:
3170 default:
3171 retval
3172 = cris_unknown_syscall (current_cpu, pc,
3173 "Unimplemented syscall: %d "
3174 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3175 callnum, arg1, arg2, arg3, arg4, arg5,
3176 arg6);
3177 }
3178 }
3179
3180 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
3181 if (callnum == TARGET_SYS_open)
3182 {
3183 current_cpu->last_open_fd = retval;
3184 current_cpu->last_open_flags = arg2;
3185 }
3186
3187 current_cpu->last_syscall = callnum;
3188
3189 /* A system call is a rescheduling point. For the time being, we don't
3190 reschedule anywhere else. */
3191 if (current_cpu->m1threads != 0
3192 /* We need to schedule off from an exiting thread that is the
3193 second-last one. */
3194 || (current_cpu->thread_data != NULL
3195 && current_cpu->thread_data[threadno].cpu_context == NULL))
3196 {
3197 bfd_byte retval_buf[4];
3198
3199 current_cpu->thread_data[threadno].last_execution
3200 = TARGET_TIME_MS (current_cpu);
3201 bfd_putl32 (retval, retval_buf);
3202 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
3203
3204 current_cpu->thread_data[threadno].at_syscall = 1;
3205 reschedule (current_cpu);
3206
3207 (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
3208 retval = bfd_getl32 (retval_buf);
3209 }
3210
3211 return retval;
3212 }
3213
3214 /* Callback from simulator write saying that the pipe at (reader, writer)
3215 is now non-empty (so the writer should wait until the pipe is empty, at
3216 least not write to this or any other pipe). Simplest is to just wait
3217 until the pipe is empty. */
3218
3219 static void
3220 cris_pipe_nonempty (host_callback *cb ATTRIBUTE_UNUSED,
3221 int reader, int writer)
3222 {
3223 SIM_CPU *cpu = current_cpu_for_cb_callback;
3224 const bfd_byte zeros[4] = { 0, 0, 0, 0 };
3225
3226 /* It's the current thread: we just have to re-run the current
3227 syscall instruction (presumably "break 13") and change the syscall
3228 to the special simulator-wait code. Oh, and set a marker that
3229 we're waiting, so we can disambiguate the special call from a
3230 program error.
3231
3232 This function may be called multiple times between cris_pipe_empty,
3233 but we must avoid e.g. decreasing PC every time. Check fd markers
3234 to tell. */
3235 if (cpu->thread_data == NULL)
3236 {
3237 sim_io_eprintf (CPU_STATE (cpu),
3238 "Terminating simulation due to writing pipe rd:wr %d:%d"
3239 " from one single thread\n", reader, writer);
3240 sim_engine_halt (CPU_STATE (cpu), cpu,
3241 NULL, sim_pc_get (cpu), sim_stopped, SIM_SIGILL);
3242 }
3243 else if (cpu->thread_data[cpu->threadno].pipe_write_fd == 0)
3244 {
3245 cpu->thread_data[cpu->threadno].pipe_write_fd = writer;
3246 cpu->thread_data[cpu->threadno].pipe_read_fd = reader;
3247 /* FIXME: We really shouldn't change registers other than R10 in
3248 syscalls (like R9), here or elsewhere. */
3249 (*CPU_REG_STORE (cpu)) (cpu, H_GR_R9, (bfd_byte *) zeros, 4);
3250 sim_pc_set (cpu, sim_pc_get (cpu) - 2);
3251 }
3252 }
3253
3254 /* Callback from simulator close or read call saying that the pipe at
3255 (reader, writer) is now empty (so the writer can write again, perhaps
3256 leave a waiting state). If there are bytes remaining, they couldn't be
3257 consumed (perhaps due to the pipe closing). */
3258
3259 static void
3260 cris_pipe_empty (host_callback *cb,
3261 int reader,
3262 int writer)
3263 {
3264 int i;
3265 SIM_CPU *cpu = current_cpu_for_cb_callback;
3266 bfd_byte r10_buf[4];
3267 int remaining
3268 = cb->pipe_buffer[writer].size - cb->pipe_buffer[reader].size;
3269
3270 /* We need to find the thread that waits for this pipe. */
3271 for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
3272 if (cpu->thread_data[i].cpu_context
3273 && cpu->thread_data[i].pipe_write_fd == writer)
3274 {
3275 int retval;
3276
3277 /* Temporarily switch to this cpu context, so we can change the
3278 PC by ordinary calls. */
3279
3280 memcpy (cpu->thread_data[cpu->threadno].cpu_context,
3281 &cpu->cpu_data_placeholder,
3282 cpu->thread_cpu_data_size);
3283 memcpy (&cpu->cpu_data_placeholder,
3284 cpu->thread_data[i].cpu_context,
3285 cpu->thread_cpu_data_size);
3286
3287 /* The return value is supposed to contain the number of
3288 written bytes, which is the number of bytes requested and
3289 returned at the write call. You might think the right
3290 thing is to adjust the return-value to be only the
3291 *consumed* number of bytes, but it isn't. We're only
3292 called if the pipe buffer is fully consumed or it is being
3293 closed, possibly with remaining bytes. For the latter
3294 case, the writer is still supposed to see success for
3295 PIPE_BUF bytes (a constant which we happen to know and is
3296 unlikely to change). The return value may also be a
3297 negative number; an error value. This case is covered
3298 because "remaining" is always >= 0. */
3299 (*CPU_REG_FETCH (cpu)) (cpu, H_GR_R10, r10_buf, 4);
3300 retval = (int) bfd_getl_signed_32 (r10_buf);
3301 if (retval - remaining > TARGET_PIPE_BUF)
3302 {
3303 bfd_putl32 (retval - remaining, r10_buf);
3304 (*CPU_REG_STORE (cpu)) (cpu, H_GR_R10, r10_buf, 4);
3305 }
3306 sim_pc_set (cpu, sim_pc_get (cpu) + 2);
3307 memcpy (cpu->thread_data[i].cpu_context,
3308 &cpu->cpu_data_placeholder,
3309 cpu->thread_cpu_data_size);
3310 memcpy (&cpu->cpu_data_placeholder,
3311 cpu->thread_data[cpu->threadno].cpu_context,
3312 cpu->thread_cpu_data_size);
3313 cpu->thread_data[i].pipe_read_fd = 0;
3314 cpu->thread_data[i].pipe_write_fd = 0;
3315 return;
3316 }
3317
3318 abort ();
3319 }
3320
3321 /* We have a simulator-specific notion of time. See TARGET_TIME. */
3322
3323 static long
3324 cris_time (host_callback *cb ATTRIBUTE_UNUSED, long *t)
3325 {
3326 long retval = TARGET_TIME (current_cpu_for_cb_callback);
3327 if (t)
3328 *t = retval;
3329 return retval;
3330 }
3331
3332 /* Set target-specific callback data. */
3333
3334 void
3335 cris_set_callbacks (host_callback *cb)
3336 {
3337 /* Yeargh, have to cast away constness to avoid warnings. */
3338 cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_map;
3339 cb->errno_map = (CB_TARGET_DEFS_MAP *) errno_map;
3340
3341 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3342 parameter to cb_store_target_endian will make st_size negative.
3343 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3344 *unsigned*, and/or add syntax for signed-ness. */
3345 cb->stat_map = stat_map;
3346 cb->open_map = (CB_TARGET_DEFS_MAP *) open_map;
3347 cb->pipe_nonempty = cris_pipe_nonempty;
3348 cb->pipe_empty = cris_pipe_empty;
3349 cb->time = cris_time;
3350 }
3351
3352 /* Process an address exception. */
3353
3354 void
3355 cris_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
3356 unsigned int map, int nr_bytes, address_word addr,
3357 transfer_type transfer, sim_core_signals sig)
3358 {
3359 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
3360 transfer, sig);
3361 }