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