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