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