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