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