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