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