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