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