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