1 /* CRIS exception, interrupt, and trap (EIT) support
2 Copyright (C) 2004-2015 Free Software Foundation, Inc.
3 Contributed by Axis Communications.
5 This file is part of the GNU simulators.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "sim-options.h"
23 /* FIXME: get rid of targ-vals.h usage everywhere else. */
35 #ifdef HAVE_SYS_PARAM_H
36 #include <sys/param.h>
38 #ifdef HAVE_SYS_STAT_H
41 /* For PATH_MAX, originally. */
46 /* From ld/sysdep.h. */
48 # define SIM_PATHMAX PATH_MAX
51 # define SIM_PATHMAX MAXPATHLEN
53 # define SIM_PATHMAX 1024
57 /* The verbatim values are from asm-cris/unistd.h. */
59 #define TARGET_SYS_exit 1
60 #define TARGET_SYS_read 3
61 #define TARGET_SYS_write 4
62 #define TARGET_SYS_open 5
63 #define TARGET_SYS_close 6
64 #define TARGET_SYS_unlink 10
65 #define TARGET_SYS_time 13
66 #define TARGET_SYS_lseek 19
67 #define TARGET_SYS_getpid 20
68 #define TARGET_SYS_access 33
69 #define TARGET_SYS_kill 37
70 #define TARGET_SYS_rename 38
71 #define TARGET_SYS_pipe 42
72 #define TARGET_SYS_brk 45
73 #define TARGET_SYS_ioctl 54
74 #define TARGET_SYS_fcntl 55
75 #define TARGET_SYS_getppid 64
76 #define TARGET_SYS_setrlimit 75
77 #define TARGET_SYS_gettimeofday 78
78 #define TARGET_SYS_readlink 85
79 #define TARGET_SYS_munmap 91
80 #define TARGET_SYS_truncate 92
81 #define TARGET_SYS_ftruncate 93
82 #define TARGET_SYS_socketcall 102
83 #define TARGET_SYS_stat 106
84 #define TARGET_SYS_fstat 108
85 #define TARGET_SYS_wait4 114
86 #define TARGET_SYS_sigreturn 119
87 #define TARGET_SYS_clone 120
88 #define TARGET_SYS_uname 122
89 #define TARGET_SYS_mprotect 125
90 #define TARGET_SYS_llseek 140
91 #define TARGET_SYS_writev 146
92 #define TARGET_SYS__sysctl 149
93 #define TARGET_SYS_sched_setparam 154
94 #define TARGET_SYS_sched_getparam 155
95 #define TARGET_SYS_sched_setscheduler 156
96 #define TARGET_SYS_sched_getscheduler 157
97 #define TARGET_SYS_sched_yield 158
98 #define TARGET_SYS_sched_get_priority_max 159
99 #define TARGET_SYS_sched_get_priority_min 160
100 #define TARGET_SYS_mremap 163
101 #define TARGET_SYS_poll 168
102 #define TARGET_SYS_rt_sigaction 174
103 #define TARGET_SYS_rt_sigprocmask 175
104 #define TARGET_SYS_rt_sigsuspend 179
105 #define TARGET_SYS_getcwd 183
106 #define TARGET_SYS_ugetrlimit 191
107 #define TARGET_SYS_mmap2 192
108 #define TARGET_SYS_stat64 195
109 #define TARGET_SYS_lstat64 196
110 #define TARGET_SYS_fstat64 197
111 #define TARGET_SYS_geteuid32 201
112 #define TARGET_SYS_getuid32 199
113 #define TARGET_SYS_getegid32 202
114 #define TARGET_SYS_getgid32 200
115 #define TARGET_SYS_fcntl64 221
116 #define TARGET_SYS_set_thread_area 243
117 #define TARGET_SYS_exit_group 252
119 #define TARGET_PROT_READ 0x1
120 #define TARGET_PROT_WRITE 0x2
121 #define TARGET_PROT_EXEC 0x4
122 #define TARGET_PROT_NONE 0x0
124 #define TARGET_MAP_SHARED 0x01
125 #define TARGET_MAP_PRIVATE 0x02
126 #define TARGET_MAP_TYPE 0x0f
127 #define TARGET_MAP_FIXED 0x10
128 #define TARGET_MAP_ANONYMOUS 0x20
129 #define TARGET_MAP_DENYWRITE 0x800
131 #define TARGET_CTL_KERN 1
132 #define TARGET_CTL_VM 2
133 #define TARGET_CTL_NET 3
134 #define TARGET_CTL_PROC 4
135 #define TARGET_CTL_FS 5
136 #define TARGET_CTL_DEBUG 6
137 #define TARGET_CTL_DEV 7
138 #define TARGET_CTL_BUS 8
139 #define TARGET_CTL_ABI 9
141 #define TARGET_CTL_KERN_VERSION 4
144 #define TARGET_MREMAP_MAYMOVE 1
145 #define TARGET_MREMAP_FIXED 2
147 #define TARGET_TCGETS 0x5401
149 #define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
151 /* Seconds since 1970-01-01 to the above date + 10 minutes;
152 'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'. */
153 #define TARGET_EPOCH 1230764410
155 /* Milliseconds since start of run. We use the number of syscalls to
156 avoid introducing noise in the execution time. */
157 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
159 /* Seconds as in time(2). */
160 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
162 #define TARGET_SCHED_OTHER 0
164 #define TARGET_RLIMIT_STACK 3
165 #define TARGET_RLIMIT_NOFILE 7
167 #define SIM_TARGET_MAX_THREADS 64
168 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
170 /* From linux/sched.h. */
171 #define TARGET_CSIGNAL 0x000000ff
172 #define TARGET_CLONE_VM 0x00000100
173 #define TARGET_CLONE_FS 0x00000200
174 #define TARGET_CLONE_FILES 0x00000400
175 #define TARGET_CLONE_SIGHAND 0x00000800
176 #define TARGET_CLONE_PID 0x00001000
177 #define TARGET_CLONE_PTRACE 0x00002000
178 #define TARGET_CLONE_VFORK 0x00004000
179 #define TARGET_CLONE_PARENT 0x00008000
180 #define TARGET_CLONE_THREAD 0x00010000
181 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
183 /* From asm-cris/poll.h. */
184 #define TARGET_POLLIN 1
186 /* From asm-cris/signal.h. */
187 #define TARGET_SIG_BLOCK 0
188 #define TARGET_SIG_UNBLOCK 1
189 #define TARGET_SIG_SETMASK 2
191 #define TARGET_SIG_DFL 0
192 #define TARGET_SIG_IGN 1
193 #define TARGET_SIG_ERR ((USI)-1)
195 #define TARGET_SIGHUP 1
196 #define TARGET_SIGINT 2
197 #define TARGET_SIGQUIT 3
198 #define TARGET_SIGILL 4
199 #define TARGET_SIGTRAP 5
200 #define TARGET_SIGABRT 6
201 #define TARGET_SIGIOT 6
202 #define TARGET_SIGBUS 7
203 #define TARGET_SIGFPE 8
204 #define TARGET_SIGKILL 9
205 #define TARGET_SIGUSR1 10
206 #define TARGET_SIGSEGV 11
207 #define TARGET_SIGUSR2 12
208 #define TARGET_SIGPIPE 13
209 #define TARGET_SIGALRM 14
210 #define TARGET_SIGTERM 15
211 #define TARGET_SIGSTKFLT 16
212 #define TARGET_SIGCHLD 17
213 #define TARGET_SIGCONT 18
214 #define TARGET_SIGSTOP 19
215 #define TARGET_SIGTSTP 20
216 #define TARGET_SIGTTIN 21
217 #define TARGET_SIGTTOU 22
218 #define TARGET_SIGURG 23
219 #define TARGET_SIGXCPU 24
220 #define TARGET_SIGXFSZ 25
221 #define TARGET_SIGVTALRM 26
222 #define TARGET_SIGPROF 27
223 #define TARGET_SIGWINCH 28
224 #define TARGET_SIGIO 29
225 #define TARGET_SIGPOLL SIGIO
226 /* Actually commented out in the kernel header. */
227 #define TARGET_SIGLOST 29
228 #define TARGET_SIGPWR 30
229 #define TARGET_SIGSYS 31
231 /* From include/asm-cris/signal.h. */
232 #define TARGET_SA_NOCLDSTOP 0x00000001
233 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
234 #define TARGET_SA_SIGINFO 0x00000004
235 #define TARGET_SA_ONSTACK 0x08000000
236 #define TARGET_SA_RESTART 0x10000000
237 #define TARGET_SA_NODEFER 0x40000000
238 #define TARGET_SA_RESETHAND 0x80000000
239 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
240 #define TARGET_SA_RESTORER 0x04000000
242 /* From linux/wait.h. */
243 #define TARGET_WNOHANG 1
244 #define TARGET_WUNTRACED 2
245 #define TARGET___WNOTHREAD 0x20000000
246 #define TARGET___WALL 0x40000000
247 #define TARGET___WCLONE 0x80000000
249 /* From linux/limits.h. */
250 #define TARGET_PIPE_BUF 4096
253 #define TARGET_R_OK 4
254 #define TARGET_W_OK 2
255 #define TARGET_X_OK 1
256 #define TARGET_F_OK 0
258 static const char stat_map[] =
259 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
260 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
261 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
264 static const CB_TARGET_DEFS_MAP syscall_map[] =
266 { "open", CB_SYS_open, TARGET_SYS_open },
267 { "close", CB_SYS_close, TARGET_SYS_close },
268 { "read", CB_SYS_read, TARGET_SYS_read },
269 { "write", CB_SYS_write, TARGET_SYS_write },
270 { "lseek", CB_SYS_lseek, TARGET_SYS_lseek },
271 { "unlink", CB_SYS_unlink, TARGET_SYS_unlink },
272 { "getpid", CB_SYS_getpid, TARGET_SYS_getpid },
273 { "fstat", CB_SYS_fstat, TARGET_SYS_fstat64 },
274 { "lstat", CB_SYS_lstat, TARGET_SYS_lstat64 },
275 { "stat", CB_SYS_stat, TARGET_SYS_stat64 },
276 { "pipe", CB_SYS_pipe, TARGET_SYS_pipe },
277 { "rename", CB_SYS_rename, TARGET_SYS_rename },
278 { "truncate", CB_SYS_truncate, TARGET_SYS_truncate },
279 { "ftruncate", CB_SYS_ftruncate, TARGET_SYS_ftruncate },
283 /* An older, 32-bit-only stat mapping. */
284 static const char stat32_map[] =
285 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
286 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
287 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
289 /* Map for calls using the 32-bit struct stat. Primarily used by the
290 newlib Linux mapping. */
291 static const CB_TARGET_DEFS_MAP syscall_stat32_map[] =
293 { "fstat", CB_SYS_fstat, TARGET_SYS_fstat },
294 { "stat", CB_SYS_stat, TARGET_SYS_stat },
298 /* Giving the true value for the running sim process will lead to
299 non-time-invariant behavior. */
300 #define TARGET_PID 42
302 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
303 we did, we'd still don't get a register number with the "16" offset. */
304 #define TARGET_SRP_REGNUM (16+11)
306 /* Extracted by applying
307 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
308 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
309 adjusting the synonyms. */
311 static const CB_TARGET_DEFS_MAP errno_map[] =
314 { "EPERM", EPERM, 1 },
317 { "ENOENT", ENOENT, 2 },
320 { "ESRCH", ESRCH, 3 },
323 { "EINTR", EINTR, 4 },
329 { "ENXIO", ENXIO, 6 },
332 { "E2BIG", E2BIG, 7 },
335 { "ENOEXEC", ENOEXEC, 8 },
338 { "EBADF", EBADF, 9 },
341 { "ECHILD", ECHILD, 10 },
344 { "EAGAIN", EAGAIN, 11 },
347 { "ENOMEM", ENOMEM, 12 },
350 { "EACCES", EACCES, 13 },
353 { "EFAULT", EFAULT, 14 },
356 { "ENOTBLK", ENOTBLK, 15 },
359 { "EBUSY", EBUSY, 16 },
362 { "EEXIST", EEXIST, 17 },
365 { "EXDEV", EXDEV, 18 },
368 { "ENODEV", ENODEV, 19 },
371 { "ENOTDIR", ENOTDIR, 20 },
374 { "EISDIR", EISDIR, 21 },
377 { "EINVAL", EINVAL, 22 },
380 { "ENFILE", ENFILE, 23 },
383 { "EMFILE", EMFILE, 24 },
386 { "ENOTTY", ENOTTY, 25 },
389 { "ETXTBSY", ETXTBSY, 26 },
392 { "EFBIG", EFBIG, 27 },
395 { "ENOSPC", ENOSPC, 28 },
398 { "ESPIPE", ESPIPE, 29 },
401 { "EROFS", EROFS, 30 },
404 { "EMLINK", EMLINK, 31 },
407 { "EPIPE", EPIPE, 32 },
410 { "EDOM", EDOM, 33 },
413 { "ERANGE", ERANGE, 34 },
416 { "EDEADLK", EDEADLK, 35 },
419 { "ENAMETOOLONG", ENAMETOOLONG, 36 },
422 { "ENOLCK", ENOLCK, 37 },
425 { "ENOSYS", ENOSYS, 38 },
428 { "ENOTEMPTY", ENOTEMPTY, 39 },
431 { "ELOOP", ELOOP, 40 },
434 { "EWOULDBLOCK", EWOULDBLOCK, 11 },
437 { "ENOMSG", ENOMSG, 42 },
440 { "EIDRM", EIDRM, 43 },
443 { "ECHRNG", ECHRNG, 44 },
446 { "EL2NSYNC", EL2NSYNC, 45 },
449 { "EL3HLT", EL3HLT, 46 },
452 { "EL3RST", EL3RST, 47 },
455 { "ELNRNG", ELNRNG, 48 },
458 { "EUNATCH", EUNATCH, 49 },
461 { "ENOCSI", ENOCSI, 50 },
464 { "EL2HLT", EL2HLT, 51 },
467 { "EBADE", EBADE, 52 },
470 { "EBADR", EBADR, 53 },
473 { "EXFULL", EXFULL, 54 },
476 { "ENOANO", ENOANO, 55 },
479 { "EBADRQC", EBADRQC, 56 },
482 { "EBADSLT", EBADSLT, 57 },
485 { "EDEADLOCK", EDEADLOCK, 35 },
488 { "EBFONT", EBFONT, 59 },
491 { "ENOSTR", ENOSTR, 60 },
494 { "ENODATA", ENODATA, 61 },
497 { "ETIME", ETIME, 62 },
500 { "ENOSR", ENOSR, 63 },
503 { "ENONET", ENONET, 64 },
506 { "ENOPKG", ENOPKG, 65 },
509 { "EREMOTE", EREMOTE, 66 },
512 { "ENOLINK", ENOLINK, 67 },
515 { "EADV", EADV, 68 },
518 { "ESRMNT", ESRMNT, 69 },
521 { "ECOMM", ECOMM, 70 },
524 { "EPROTO", EPROTO, 71 },
527 { "EMULTIHOP", EMULTIHOP, 72 },
530 { "EDOTDOT", EDOTDOT, 73 },
533 { "EBADMSG", EBADMSG, 74 },
536 { "EOVERFLOW", EOVERFLOW, 75 },
539 { "ENOTUNIQ", ENOTUNIQ, 76 },
542 { "EBADFD", EBADFD, 77 },
545 { "EREMCHG", EREMCHG, 78 },
548 { "ELIBACC", ELIBACC, 79 },
551 { "ELIBBAD", ELIBBAD, 80 },
554 { "ELIBSCN", ELIBSCN, 81 },
557 { "ELIBMAX", ELIBMAX, 82 },
560 { "ELIBEXEC", ELIBEXEC, 83 },
563 { "EILSEQ", EILSEQ, 84 },
566 { "ERESTART", ERESTART, 85 },
569 { "ESTRPIPE", ESTRPIPE, 86 },
572 { "EUSERS", EUSERS, 87 },
575 { "ENOTSOCK", ENOTSOCK, 88 },
578 { "EDESTADDRREQ", EDESTADDRREQ, 89 },
581 { "EMSGSIZE", EMSGSIZE, 90 },
584 { "EPROTOTYPE", EPROTOTYPE, 91 },
587 { "ENOPROTOOPT", ENOPROTOOPT, 92 },
589 #ifdef EPROTONOSUPPORT
590 { "EPROTONOSUPPORT", EPROTONOSUPPORT, 93 },
592 #ifdef ESOCKTNOSUPPORT
593 { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, 94 },
596 { "EOPNOTSUPP", EOPNOTSUPP, 95 },
599 { "EPFNOSUPPORT", EPFNOSUPPORT, 96 },
602 { "EAFNOSUPPORT", EAFNOSUPPORT, 97 },
605 { "EADDRINUSE", EADDRINUSE, 98 },
608 { "EADDRNOTAVAIL", EADDRNOTAVAIL, 99 },
611 { "ENETDOWN", ENETDOWN, 100 },
614 { "ENETUNREACH", ENETUNREACH, 101 },
617 { "ENETRESET", ENETRESET, 102 },
620 { "ECONNABORTED", ECONNABORTED, 103 },
623 { "ECONNRESET", ECONNRESET, 104 },
626 { "ENOBUFS", ENOBUFS, 105 },
629 { "EISCONN", EISCONN, 106 },
632 { "ENOTCONN", ENOTCONN, 107 },
635 { "ESHUTDOWN", ESHUTDOWN, 108 },
638 { "ETOOMANYREFS", ETOOMANYREFS, 109 },
641 { "ETIMEDOUT", ETIMEDOUT, 110 },
644 { "ECONNREFUSED", ECONNREFUSED, 111 },
647 { "EHOSTDOWN", EHOSTDOWN, 112 },
650 { "EHOSTUNREACH", EHOSTUNREACH, 113 },
653 { "EALREADY", EALREADY, 114 },
656 { "EINPROGRESS", EINPROGRESS, 115 },
659 { "ESTALE", ESTALE, 116 },
662 { "EUCLEAN", EUCLEAN, 117 },
665 { "ENOTNAM", ENOTNAM, 118 },
668 { "ENAVAIL", ENAVAIL, 119 },
671 { "EISNAM", EISNAM, 120 },
674 { "EREMOTEIO", EREMOTEIO, 121 },
677 { "EDQUOT", EDQUOT, 122 },
680 { "ENOMEDIUM", ENOMEDIUM, 123 },
683 { "EMEDIUMTYPE", EMEDIUMTYPE, 124 },
688 /* Extracted by applying
689 perl -ne 'if ($_ =~ /^#define/) { split;
690 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
691 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
692 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
693 installation and removing synonyms and unnecessary items. Don't
694 forget the end-marker. */
696 /* These we treat specially, as they're used in the fcntl F_GETFL
697 syscall. For consistency, open_map is also manually edited to use
699 #define TARGET_O_ACCMODE 0x3
700 #define TARGET_O_RDONLY 0x0
701 #define TARGET_O_WRONLY 0x1
703 static const CB_TARGET_DEFS_MAP open_map[] = {
705 { "O_ACCMODE", O_ACCMODE, TARGET_O_ACCMODE },
708 { "O_RDONLY", O_RDONLY, TARGET_O_RDONLY },
711 { "O_WRONLY", O_WRONLY, TARGET_O_WRONLY },
714 { "O_RDWR", O_RDWR, 0x2 },
717 { "O_CREAT", O_CREAT, 0x40 },
720 { "O_EXCL", O_EXCL, 0x80 },
723 { "O_NOCTTY", O_NOCTTY, 0x100 },
726 { "O_TRUNC", O_TRUNC, 0x200 },
729 { "O_APPEND", O_APPEND, 0x400 },
732 { "O_NONBLOCK", O_NONBLOCK, 0x800 },
735 { "O_NDELAY", O_NDELAY, 0x0 },
738 { "O_SYNC", O_SYNC, 0x1000 },
741 { "FASYNC", FASYNC, 0x2000 },
744 { "O_DIRECT", O_DIRECT, 0x4000 },
747 { "O_LARGEFILE", O_LARGEFILE, 0x8000 },
750 { "O_DIRECTORY", O_DIRECTORY, 0x10000 },
753 { "O_NOFOLLOW", O_NOFOLLOW, 0x20000 },
758 /* Let's be less drastic and more traceable. FIXME: mark as noreturn. */
760 sim_io_error (sd, "simulator unhandled condition at %s:%d", \
761 __FUNCTION__, __LINE__)
763 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
764 static SIM_CPU *current_cpu_for_cb_callback;
766 static int syscall_read_mem (host_callback *, struct cb_syscall *,
767 unsigned long, char *, int);
768 static int syscall_write_mem (host_callback *, struct cb_syscall *,
769 unsigned long, const char *, int);
770 static USI create_map (SIM_DESC, struct cris_sim_mmapped_page **,
772 static USI unmap_pages (SIM_DESC, struct cris_sim_mmapped_page **,
774 static USI is_mapped (SIM_DESC, struct cris_sim_mmapped_page **,
776 static void dump_statistics (SIM_CPU *current_cpu);
777 static void make_first_thread (SIM_CPU *current_cpu);
779 /* Read/write functions for system call interface. */
782 syscall_read_mem (host_callback *cb ATTRIBUTE_UNUSED,
783 struct cb_syscall *sc,
784 unsigned long taddr, char *buf, int bytes)
786 SIM_DESC sd = (SIM_DESC) sc->p1;
787 SIM_CPU *cpu = (SIM_CPU *) sc->p2;
789 return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
793 syscall_write_mem (host_callback *cb ATTRIBUTE_UNUSED,
794 struct cb_syscall *sc,
795 unsigned long taddr, const char *buf, int bytes)
797 SIM_DESC sd = (SIM_DESC) sc->p1;
798 SIM_CPU *cpu = (SIM_CPU *) sc->p2;
800 return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
803 /* When we risk running self-modified code (as in trampolines), this is
804 called from special-case insns. The silicon CRIS CPU:s have enough
805 cache snooping implemented making this a simulator-only issue. Tests:
806 gcc.c-torture/execute/931002-1.c execution, -O3 -g
807 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
810 cris_flush_simulator_decode_cache (SIM_CPU *current_cpu,
811 USI pc ATTRIBUTE_UNUSED)
813 SIM_DESC sd = CPU_STATE (current_cpu);
816 if (USING_SCACHE_P (sd))
817 scache_flush_cpu (current_cpu);
821 /* Output statistics at the end of a run. */
823 dump_statistics (SIM_CPU *current_cpu)
825 SIM_DESC sd = CPU_STATE (current_cpu);
826 CRIS_MISC_PROFILE *profp
827 = CPU_CRIS_MISC_PROFILE (current_cpu);
828 unsigned64 total = profp->basic_cycle_count;
829 const char *textmsg = "Basic clock cycles, total @: %llu\n";
831 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
832 what's included in the "total" count only. */
833 switch (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
834 & FLAG_CRIS_MISC_PROFILE_ALL)
836 case FLAG_CRIS_MISC_PROFILE_SIMPLE:
839 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED | FLAG_CRIS_MISC_PROFILE_SIMPLE):
841 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
842 total += profp->unaligned_mem_dword_count;
845 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE | FLAG_CRIS_MISC_PROFILE_SIMPLE):
846 textmsg = "Schedulable clock cycles, total @: %llu\n";
848 += (profp->memsrc_stall_count
849 + profp->memraw_stall_count
850 + profp->movemsrc_stall_count
851 + profp->movemdst_stall_count
852 + profp->mulsrc_stall_count
853 + profp->jumpsrc_stall_count
854 + profp->unaligned_mem_dword_count);
857 case FLAG_CRIS_MISC_PROFILE_ALL:
858 textmsg = "All accounted clock cycles, total @: %llu\n";
860 += (profp->memsrc_stall_count
861 + profp->memraw_stall_count
862 + profp->movemsrc_stall_count
863 + profp->movemdst_stall_count
864 + profp->movemaddr_stall_count
865 + profp->mulsrc_stall_count
866 + profp->jumpsrc_stall_count
867 + profp->branch_stall_count
868 + profp->jumptarget_stall_count
869 + profp->unaligned_mem_dword_count);
876 "Internal inconsistency at %s:%d",
878 sim_engine_halt (sd, current_cpu, NULL, 0,
879 sim_stopped, SIM_SIGILL);
882 /* Historically, these messages have gone to stderr, so we'll keep it
883 that way. It's also easier to then tell it from normal program
884 output. FIXME: Add redirect option like "run -e file". */
885 sim_io_eprintf (sd, textmsg, total);
887 /* For v32, unaligned_mem_dword_count should always be 0. For
888 v10, memsrc_stall_count should always be 0. */
889 sim_io_eprintf (sd, "Memory source stall cycles: %llu\n",
890 (unsigned long long) (profp->memsrc_stall_count
891 + profp->unaligned_mem_dword_count));
892 sim_io_eprintf (sd, "Memory read-after-write stall cycles: %llu\n",
893 (unsigned long long) profp->memraw_stall_count);
894 sim_io_eprintf (sd, "Movem source stall cycles: %llu\n",
895 (unsigned long long) profp->movemsrc_stall_count);
896 sim_io_eprintf (sd, "Movem destination stall cycles: %llu\n",
897 (unsigned long long) profp->movemdst_stall_count);
898 sim_io_eprintf (sd, "Movem address stall cycles: %llu\n",
899 (unsigned long long) profp->movemaddr_stall_count);
900 sim_io_eprintf (sd, "Multiplication source stall cycles: %llu\n",
901 (unsigned long long) profp->mulsrc_stall_count);
902 sim_io_eprintf (sd, "Jump source stall cycles: %llu\n",
903 (unsigned long long) profp->jumpsrc_stall_count);
904 sim_io_eprintf (sd, "Branch misprediction stall cycles: %llu\n",
905 (unsigned long long) profp->branch_stall_count);
906 sim_io_eprintf (sd, "Jump target stall cycles: %llu\n",
907 (unsigned long long) profp->jumptarget_stall_count);
910 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
911 Return 1 if a overlap detected, 0 otherwise. */
914 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED,
915 struct cris_sim_mmapped_page **rootp,
918 struct cris_sim_mmapped_page *mapp;
920 if (len == 0 || (len & 8191))
923 /* Iterate over the reverse-address sorted pages until we find a page in
924 or lower than the checked area. */
925 for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
926 if (mapp->addr < addr + len && mapp->addr >= addr)
932 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
933 Return 1 if the whole area is mapped, 0 otherwise. */
936 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED,
937 struct cris_sim_mmapped_page **rootp,
940 struct cris_sim_mmapped_page *mapp;
942 if (len == 0 || (len & 8191))
945 /* Iterate over the reverse-address sorted pages until we find a page
946 lower than the checked area. */
947 for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
948 if (addr == mapp->addr && len == 8192)
950 else if (addr + len > mapp->addr)
956 /* Debug helper; to be run from gdb. */
959 cris_dump_map (SIM_CPU *current_cpu)
961 struct cris_sim_mmapped_page *mapp;
964 for (mapp = current_cpu->highest_mmapped_page,
965 start = mapp == NULL ? 0 : mapp->addr + 8192,
966 end = mapp == NULL ? 0 : mapp->addr + 8191;
970 if (mapp->addr != start - 8192)
972 sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
973 end = mapp->addr + 8191;
979 if (current_cpu->highest_mmapped_page != NULL)
980 sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
983 /* Create mmapped memory. ADDR is -1 if any address will do. Caller
984 must make sure that the address isn't already mapped. */
987 create_map (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
990 struct cris_sim_mmapped_page *mapp;
991 struct cris_sim_mmapped_page **higher_prevp = rootp;
992 USI new_addr = 0x40000000;
994 if (addr != (USI) -1)
996 else if (*rootp && rootp[0]->addr >= new_addr)
997 new_addr = rootp[0]->addr + 8192;
1004 /* Which is better: return an error for this, or just round it up? */
1007 /* Do a recursive call for each page in the request. */
1008 for (page_addr = new_addr; len != 0; page_addr += 8192, len -= 8192)
1009 if (create_map (sd, rootp, page_addr, 8192) >= (USI) -8191)
1016 mapp != NULL && mapp->addr > new_addr;
1018 higher_prevp = &mapp->prev;
1020 /* Assert for consistency that we don't create duplicate maps. */
1021 if (is_mapped (sd, rootp, new_addr, len))
1024 /* Allocate the new page, on the next higher page from the last one
1025 allocated, and link in the new descriptor before previous ones. */
1026 mapp = malloc (sizeof (*mapp));
1029 return (USI) -ENOMEM;
1031 sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
1035 mapp->addr = new_addr;
1036 mapp->prev = *higher_prevp;
1037 *higher_prevp = mapp;
1042 /* Unmap one or more pages. */
1045 unmap_pages (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
1048 struct cris_sim_mmapped_page *mapp;
1049 struct cris_sim_mmapped_page **higher_prevp = rootp;
1057 /* Which is better: return an error for this, or just round it up? */
1060 /* Loop backwards to make each call is O(1) over the number of pages
1061 allocated, if we're unmapping from the high end of the pages. */
1062 for (page_addr = addr + len - 8192;
1065 if (unmap_pages (sd, rootp, page_addr, 8192))
1068 if (unmap_pages (sd, rootp, addr, 8192))
1074 for (mapp = *rootp; mapp != NULL && mapp->addr > addr; mapp = mapp->prev)
1075 higher_prevp = &mapp->prev;
1077 if (mapp == NULL || mapp->addr != addr)
1080 *higher_prevp = mapp->prev;
1081 sim_core_detach (sd, NULL, 0, 0, addr);
1086 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1089 sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
1091 SIM_DESC sd = CPU_STATE (current_cpu);
1093 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
1097 /* Handlers from the CGEN description that should not be called. */
1100 cris_bmod_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
1101 UINT srcreg ATTRIBUTE_UNUSED,
1102 USI dstreg ATTRIBUTE_UNUSED)
1104 SIM_DESC sd = CPU_STATE (current_cpu);
1109 h_supr_set_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
1110 UINT index ATTRIBUTE_UNUSED,
1111 USI page ATTRIBUTE_UNUSED,
1112 USI newval ATTRIBUTE_UNUSED)
1114 SIM_DESC sd = CPU_STATE (current_cpu);
1119 h_supr_get_handler (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
1120 UINT index ATTRIBUTE_UNUSED,
1121 USI page ATTRIBUTE_UNUSED)
1123 SIM_DESC sd = CPU_STATE (current_cpu);
1127 /* Swap one context for another. */
1130 schedule (SIM_CPU *current_cpu, int next)
1132 /* Need to mark context-switches in the trace output. */
1133 if ((CPU_CRIS_MISC_PROFILE (current_cpu)->flags
1134 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE))
1135 cris_trace_printf (CPU_STATE (current_cpu), current_cpu,
1138 /* Copy the current context (if there is one) to its slot. */
1139 if (current_cpu->thread_data[current_cpu->threadno].cpu_context)
1140 memcpy (current_cpu->thread_data[current_cpu->threadno].cpu_context,
1141 ¤t_cpu->cpu_data_placeholder,
1142 current_cpu->thread_cpu_data_size);
1144 /* Copy the new context from its slot. */
1145 memcpy (¤t_cpu->cpu_data_placeholder,
1146 current_cpu->thread_data[next].cpu_context,
1147 current_cpu->thread_cpu_data_size);
1149 /* Update needed stuff to indicate the new context. */
1150 current_cpu->threadno = next;
1152 /* Handle pending signals. */
1153 if (current_cpu->thread_data[next].sigpending
1154 /* We don't run nested signal handlers. This means that pause(2)
1155 and sigsuspend(2) do not work in sighandlers, but that
1156 shouldn't be too hard a restriction. It also greatly
1157 simplifies the code. */
1158 && current_cpu->thread_data[next].cpu_context_atsignal == NULL)
1162 /* See if there's really a pending, non-blocked handler. We don't
1163 queue signals, so just use the first one in ascending order. */
1164 for (sig = 0; sig < 64; sig++)
1165 if (current_cpu->thread_data[next].sigdata[sig].pending
1166 && !current_cpu->thread_data[next].sigdata[sig].blocked)
1172 USI pc = sim_pc_get (current_cpu);
1174 /* It's simpler to save the CPU context inside the simulator
1175 than on the stack. */
1176 current_cpu->thread_data[next].cpu_context_atsignal
1178 ->make_thread_cpu_data) (current_cpu,
1179 current_cpu->thread_data[next]
1182 (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
1183 sp = bfd_getl32 (regbuf);
1185 /* Make sure we have an aligned stack. */
1188 /* Make room for the signal frame, aligned. FIXME: Check that
1189 the memory exists, map it in if absent. (BTW, should also
1190 implement on-access automatic stack allocation). */
1193 /* This isn't the same signal frame as the kernel uses, because
1194 we don't want to bother getting all registers on and off the
1197 /* First, we store the currently blocked signals. */
1199 for (i = 0; i < 32; i++)
1201 |= current_cpu->thread_data[next].sigdata[i + 1].blocked << i;
1202 sim_core_write_aligned_4 (current_cpu, pc, 0, sp, blocked);
1204 for (i = 0; i < 31; i++)
1206 |= current_cpu->thread_data[next].sigdata[i + 33].blocked << i;
1207 sim_core_write_aligned_4 (current_cpu, pc, 0, sp + 4, blocked);
1209 /* Then, the actual instructions. This is CPU-specific, but we
1210 use instructions from the common subset for v10 and v32 which
1211 should be safe for the time being but could be parametrized
1213 /* MOVU.W [PC+],R9. */
1214 sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 8, 0x9c5f);
1215 /* .WORD TARGET_SYS_sigreturn. */
1216 sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 10,
1217 TARGET_SYS_sigreturn);
1219 sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 12, 0xe93d);
1221 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1222 instruction. Still, it doesn't matter because v10 has no
1223 delay slot for BREAK so it will not be executed). */
1224 sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 16, 0x05b0);
1226 /* Modify registers to hold the right values for the sighandler
1227 context: updated stackpointer and return address pointing to
1228 the sigreturn stub. */
1229 bfd_putl32 (sp, regbuf);
1230 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
1231 bfd_putl32 (sp + 8, regbuf);
1232 (*CPU_REG_STORE (current_cpu)) (current_cpu, TARGET_SRP_REGNUM,
1235 current_cpu->thread_data[next].sigdata[sig].pending = 0;
1237 /* Block this signal (for the duration of the sighandler). */
1238 current_cpu->thread_data[next].sigdata[sig].blocked = 1;
1240 sim_pc_set (current_cpu, current_cpu->sighandler[sig]);
1241 bfd_putl32 (sig, regbuf);
1242 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10,
1245 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1246 needed all this for, specifies a SA_SIGINFO call but treats it
1247 like an ordinary sighandler; only the signal number argument is
1248 inspected. To make future need to implement SA_SIGINFO
1249 correctly possible, we set the siginfo argument register to a
1250 magic (hopefully non-address) number. (NB: then, you should
1251 just need to pass the siginfo argument; it seems you probably
1252 don't need to implement the specific rt_sigreturn.) */
1253 bfd_putl32 (0xbad5161f, regbuf);
1254 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R11,
1257 /* The third argument is unused and the kernel sets it to 0. */
1258 bfd_putl32 (0, regbuf);
1259 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R12,
1264 /* No, there actually was no pending signal for this thread. Reset
1266 current_cpu->thread_data[next].sigpending = 0;
1270 /* Reschedule the simplest possible way until something else is absolutely
1272 - A. Find the next process (round-robin) that doesn't have at_syscall
1274 - B. If there is none, just run the next process, round-robin.
1275 - Clear at_syscall for the current process. */
1278 reschedule (SIM_CPU *current_cpu)
1280 SIM_DESC sd = CPU_STATE (current_cpu);
1283 /* Iterate over all thread slots, because after a few thread creations
1284 and exits, we don't know where the live ones are. */
1285 for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
1286 i != current_cpu->threadno;
1287 i = (i + 1) % SIM_TARGET_MAX_THREADS)
1288 if (current_cpu->thread_data[i].cpu_context
1289 && current_cpu->thread_data[i].at_syscall == 0)
1291 schedule (current_cpu, i);
1295 /* Pick any next live thread. */
1296 for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
1297 i != current_cpu->threadno;
1298 i = (i + 1) % SIM_TARGET_MAX_THREADS)
1299 if (current_cpu->thread_data[i].cpu_context)
1301 schedule (current_cpu, i);
1305 /* More than one live thread, but we couldn't find the next one? */
1309 /* Set up everything to receive (or IGN) an incoming signal to the
1313 deliver_signal (SIM_CPU *current_cpu, int sig, unsigned int pid)
1316 USI pc = sim_pc_get (current_cpu);
1318 /* Find the thread index of the pid. */
1319 for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
1320 /* Apparently it's ok to send signals to zombies (so a check for
1321 current_cpu->thread_data[i].cpu_context != NULL would be
1323 if (current_cpu->thread_data[i].threadid == pid - TARGET_PID)
1326 switch (current_cpu->sighandler[sig])
1328 case TARGET_SIG_DFL:
1331 /* The following according to the glibc
1332 documentation. (The kernel code has non-obvious
1333 execution paths.) */
1336 case TARGET_SIGSEGV:
1338 case TARGET_SIGABRT:
1339 case TARGET_SIGTRAP:
1342 case TARGET_SIGTERM:
1344 case TARGET_SIGQUIT:
1345 case TARGET_SIGKILL:
1348 case TARGET_SIGALRM:
1349 case TARGET_SIGVTALRM:
1350 case TARGET_SIGPROF:
1351 case TARGET_SIGSTOP:
1353 case TARGET_SIGPIPE:
1354 case TARGET_SIGLOST:
1355 case TARGET_SIGXCPU:
1356 case TARGET_SIGXFSZ:
1357 case TARGET_SIGUSR1:
1358 case TARGET_SIGUSR2:
1359 sim_io_eprintf (CPU_STATE (current_cpu),
1360 "Exiting pid %d due to signal %d\n",
1362 sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
1363 NULL, pc, sim_stopped,
1364 sig == TARGET_SIGABRT
1365 ? SIM_SIGABRT : SIM_SIGILL);
1368 /* The default for all other signals is to be ignored. */
1373 case TARGET_SIG_IGN:
1376 case TARGET_SIGKILL:
1377 case TARGET_SIGSTOP:
1378 /* Can't ignore these signals. */
1379 sim_io_eprintf (CPU_STATE (current_cpu),
1380 "Exiting pid %d due to signal %d\n",
1382 sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
1383 NULL, pc, sim_stopped, SIM_SIGILL);
1392 /* Mark the signal as pending, making schedule () check
1393 closer. The signal will be handled when the thread is
1394 scheduled and the signal is unblocked. */
1395 current_cpu->thread_data[i].sigdata[sig].pending = 1;
1396 current_cpu->thread_data[i].sigpending = 1;
1401 sim_io_eprintf (CPU_STATE (current_cpu),
1402 "Unimplemented signal: %d\n", sig);
1403 sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc,
1404 sim_stopped, SIM_SIGILL);
1409 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu)),
1413 /* Make the vector and the first item, the main thread. */
1416 make_first_thread (SIM_CPU *current_cpu)
1418 SIM_DESC sd = CPU_STATE (current_cpu);
1419 current_cpu->thread_data
1421 SIM_TARGET_MAX_THREADS
1422 * sizeof (current_cpu->thread_data[0]));
1423 current_cpu->thread_data[0].cpu_context
1424 = (*current_cpu->make_thread_cpu_data) (current_cpu,
1426 ->cpu_data_placeholder);
1427 current_cpu->thread_data[0].parent_threadid = -1;
1429 /* For good measure. */
1430 if (TARGET_SIG_DFL != 0)
1434 /* Handle unknown system calls. Returns (if it does) the syscall
1438 cris_unknown_syscall (SIM_CPU *current_cpu, USI pc, char *s, ...)
1440 SIM_DESC sd = CPU_STATE (current_cpu);
1441 host_callback *cb = STATE_CALLBACK (sd);
1443 if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP
1444 || cris_unknown_syscall_action == CRIS_USYSC_MSG_ENOSYS)
1449 sim_io_evprintf (sd, s, ap);
1452 if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP)
1453 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
1456 return -cb_host_to_target_errno (cb, ENOSYS);
1459 /* Main function: the handler of the "break 13" syscall insn. */
1462 cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
1463 USI arg2, USI arg3, USI arg4, USI arg5, USI arg6,
1467 SIM_DESC sd = CPU_STATE (current_cpu);
1468 host_callback *cb = STATE_CALLBACK (sd);
1470 int threadno = current_cpu->threadno;
1472 current_cpu->syscalls++;
1474 CB_SYSCALL_INIT (&s);
1480 /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need
1481 to sign-extend the lseek offset to be passed as a signed number,
1482 else we'll truncate it to something > 2GB on hosts where sizeof
1483 long > sizeof USI. We avoid doing it for all syscalls, as arg2 is
1484 e.g. an address for some syscalls. */
1485 if (callnum == TARGET_SYS_lseek)
1488 if (callnum == TARGET_SYS_exit_group
1489 || (callnum == TARGET_SYS_exit && current_cpu->m1threads == 0))
1491 if (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
1492 & FLAG_CRIS_MISC_PROFILE_ALL)
1493 dump_statistics (current_cpu);
1494 sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, arg1);
1498 s.p2 = (PTR) current_cpu;
1499 s.read_mem = syscall_read_mem;
1500 s.write_mem = syscall_write_mem;
1502 current_cpu_for_cb_callback = current_cpu;
1504 if (cb_syscall (cb, &s) != CB_RC_OK)
1507 sim_io_eprintf (sd, "Break 13: invalid %d? Returned %ld\n", callnum,
1509 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
1512 retval = s.result == -1 ? -s.errcode : s.result;
1514 if (s.errcode != 0 && s.errcode == cb_host_to_target_errno (cb, ENOSYS))
1516 /* If the generic simulator call said ENOSYS, then let's try the
1517 ones we know ourselves.
1519 The convention is to provide *very limited* functionality on an
1520 as-needed basis, only what's covered by the test-suite, tests
1521 added when functionality changes and abort with a descriptive
1522 message for *everything* else. Where there's no test-case, we
1527 /* It's a pretty safe bet that the "old setup() system call"
1528 number will not be re-used; we can't say the same for higher
1529 numbers. We treat this simulator-generated call as "wait
1530 forever"; we re-run this insn. The wait is ended by a
1531 callback. Sanity check that this is the reason we got
1533 if (current_cpu->thread_data == NULL
1534 || (current_cpu->thread_data[threadno].pipe_write_fd == 0))
1535 goto unimplemented_syscall;
1537 sim_pc_set (current_cpu, pc);
1541 case TARGET_SYS_fcntl64:
1542 case TARGET_SYS_fcntl:
1547 Glibc checks stdin, stdout and stderr fd:s for
1548 close-on-exec security sanity. We just need to provide a
1549 OK return value. If we really need to have a
1550 close-on-exec flag true, we could just do a real fcntl
1556 /* F_SETFD. Just ignore attempts to set the close-on-exec
1562 /* F_GETFL. Check for the special case for open+fdopen. */
1563 if (current_cpu->last_syscall == TARGET_SYS_open
1564 && arg1 == current_cpu->last_open_fd)
1566 retval = current_cpu->last_open_flags & TARGET_O_ACCMODE;
1571 /* Because we can't freopen fd:s 0, 1, 2 to mean
1572 something else than stdin, stdout and stderr
1573 (sim/common/syscall.c:cb_syscall special cases fd
1574 0, 1 and 2), we know what flags that we can
1575 sanely return for these fd:s. */
1576 retval = TARGET_O_RDONLY;
1579 else if (arg1 == 1 || arg1 == 2)
1581 retval = TARGET_O_WRONLY;
1586 /* Nothing else is implemented. */
1588 = cris_unknown_syscall (current_cpu, pc,
1589 "Unimplemented %s syscall "
1590 "(fd: 0x%lx: cmd: 0x%lx arg: "
1592 callnum == TARGET_SYS_fcntl
1593 ? "fcntl" : "fcntl64",
1594 (unsigned long) (USI) arg1,
1595 (unsigned long) (USI) arg2,
1596 (unsigned long) (USI) arg3);
1601 case TARGET_SYS_uname:
1603 /* Fill in a few constants to appease glibc. */
1604 static char sim_utsname[6][65] =
1610 "cris", /* Overwritten below. */
1614 /* Having the hardware type in Linux equal to the bfd
1615 printable name is deliberate: if you make config.guess
1616 work on your Linux-type system the usual way, it
1617 probably will; either the bfd printable_name or the
1618 ambiguous arch_name. */
1619 strcpy (sim_utsname[4], STATE_ARCHITECTURE (sd)->printable_name);
1621 if ((s.write_mem) (cb, &s, arg1, (const char *) sim_utsname,
1622 sizeof (sim_utsname))
1623 != sizeof (sim_utsname))
1624 retval = -cb_host_to_target_errno (cb, EFAULT);
1630 case TARGET_SYS_geteuid32:
1631 /* We tell the truth with these. Maybe we shouldn't, but it
1632 should match the "stat" information. */
1633 retval = geteuid ();
1636 case TARGET_SYS_getuid32:
1640 case TARGET_SYS_getegid32:
1641 retval = getegid ();
1644 case TARGET_SYS_getgid32:
1648 case TARGET_SYS_brk:
1649 /* Most often, we just return the argument, like the Linux
1654 retval = current_cpu->endbrk;
1655 else if (arg1 <= current_cpu->endmem)
1656 current_cpu->endbrk = arg1;
1659 USI new_end = (arg1 + 8191) & ~8191;
1661 /* If the simulator wants to brk more than a certain very
1662 large amount, something is wrong. FIXME: Return an error
1663 or abort? Have command-line selectable? */
1664 if (new_end - current_cpu->endmem > SIM_MAX_ALLOC_CHUNK)
1666 current_cpu->endbrk = current_cpu->endmem;
1667 retval = current_cpu->endmem;
1671 sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
1672 current_cpu->endmem,
1673 new_end - current_cpu->endmem,
1675 current_cpu->endbrk = arg1;
1676 current_cpu->endmem = new_end;
1680 case TARGET_SYS_getpid:
1681 /* Correct until CLONE_THREAD is implemented. */
1682 retval = current_cpu->thread_data == NULL
1684 : TARGET_PID + current_cpu->thread_data[threadno].threadid;
1687 case TARGET_SYS_getppid:
1688 /* Correct until CLONE_THREAD is implemented. */
1689 retval = current_cpu->thread_data == NULL
1692 + current_cpu->thread_data[threadno].parent_threadid);
1695 case TARGET_SYS_mmap2:
1704 /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1705 still masked away this bit, so let's just ignore
1707 flags &= ~TARGET_MAP_DENYWRITE;
1709 /* If the simulator wants to mmap more than the very large
1710 limit, something is wrong. FIXME: Return an error or
1711 abort? Have command-line selectable? */
1712 if (len > SIM_MAX_ALLOC_CHUNK)
1714 retval = -cb_host_to_target_errno (cb, ENOMEM);
1718 if ((prot != (TARGET_PROT_READ | TARGET_PROT_WRITE)
1720 != (TARGET_PROT_READ
1722 | TARGET_PROT_EXEC))
1723 && (prot != (TARGET_PROT_READ | TARGET_PROT_EXEC))
1724 && prot != TARGET_PROT_READ)
1725 || (flags != (TARGET_MAP_ANONYMOUS | TARGET_MAP_PRIVATE)
1726 && flags != TARGET_MAP_PRIVATE
1727 && flags != (TARGET_MAP_ANONYMOUS
1728 | TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
1729 && flags != (TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
1730 && flags != TARGET_MAP_SHARED)
1732 && prot != TARGET_PROT_READ
1733 && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
1734 && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
1735 || (fd == (USI) -1 && pgoff != 0)
1736 || (fd != (USI) -1 && (flags & TARGET_MAP_ANONYMOUS)))
1739 = cris_unknown_syscall (current_cpu, pc,
1740 "Unimplemented mmap2 call "
1741 "(0x%lx, 0x%lx, 0x%lx, "
1742 "0x%lx, 0x%lx, 0x%lx)\n",
1743 (unsigned long) arg1,
1744 (unsigned long) arg2,
1745 (unsigned long) arg3,
1746 (unsigned long) arg4,
1747 (unsigned long) arg5,
1748 (unsigned long) arg6);
1751 else if (fd != (USI) -1)
1758 /* A non-aligned argument is allowed for files. */
1759 USI newlen = (len + 8191) & ~8191;
1761 /* We only support read, read|exec, and read|write,
1762 which we should already have checked. Check again
1764 if (prot != TARGET_PROT_READ
1765 && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
1766 && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
1769 if (flags & TARGET_MAP_FIXED)
1770 unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
1772 else if (is_mapped (sd, ¤t_cpu->highest_mmapped_page,
1777 = create_map (sd, ¤t_cpu->highest_mmapped_page,
1778 addr != 0 || (flags & TARGET_MAP_FIXED)
1782 if (newaddr >= (USI) -8191)
1785 retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
1789 /* We were asked for MAP_FIXED, but couldn't. */
1790 if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
1793 unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
1795 retval = -cb_host_to_target_errno (cb, EINVAL);
1799 /* Find the current position in the file. */
1800 s.func = TARGET_SYS_lseek;
1804 if (cb_syscall (cb, &s) != CB_RC_OK)
1811 /* Move to the correct offset in the file. */
1812 s.func = TARGET_SYS_lseek;
1814 s.arg2 = pgoff*8192;
1816 if (cb_syscall (cb, &s) != CB_RC_OK)
1822 /* Use the standard read callback to read in "len"
1824 s.func = TARGET_SYS_read;
1828 if (cb_syscall (cb, &s) != CB_RC_OK)
1831 /* If the result is a page or more lesser than what
1832 was requested, something went wrong. */
1833 if (len >= 8192 && (USI) s.result <= len - 8192)
1836 /* After reading, we need to go back to the previous
1837 position in the file. */
1838 s.func = TARGET_SYS_lseek;
1842 if (cb_syscall (cb, &s) != CB_RC_OK)
1844 if (pos != (USI) s.result)
1851 USI newlen = (len + 8191) & ~8191;
1854 if (flags & TARGET_MAP_FIXED)
1855 unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
1857 else if (is_mapped (sd, ¤t_cpu->highest_mmapped_page,
1861 newaddr = create_map (sd, ¤t_cpu->highest_mmapped_page,
1862 addr != 0 || (flags & TARGET_MAP_FIXED)
1866 if (newaddr >= (USI) -8191)
1867 retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
1871 if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
1874 unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
1876 retval = -cb_host_to_target_errno (cb, EINVAL);
1883 case TARGET_SYS_mprotect:
1885 /* We only cover the case of linuxthreads mprotecting out
1886 its stack guard page and of dynamic loading mprotecting
1887 away the data (for some reason the whole library, then
1888 mprotects away the data part and mmap-FIX:es it again. */
1893 if (prot != TARGET_PROT_NONE
1894 || !is_mapped_only (sd, ¤t_cpu->highest_mmapped_page,
1895 addr, (len + 8191) & ~8191))
1898 = cris_unknown_syscall (current_cpu, pc,
1899 "Unimplemented mprotect call "
1900 "(0x%lx, 0x%lx, 0x%lx)\n",
1901 (unsigned long) arg1,
1902 (unsigned long) arg2,
1903 (unsigned long) arg3);
1907 /* Just ignore this. We could make this equal to munmap,
1908 but then we'd have to make sure no anon mmaps gets this
1909 address before a subsequent MAP_FIXED mmap intended to
1915 case TARGET_SYS_ioctl:
1917 /* We support only a very limited functionality: checking
1918 stdout with TCGETS to perform the isatty function. The
1919 TCGETS ioctl isn't actually performed or the result used by
1920 an isatty () caller in a "hello, world" program; only the
1921 return value is then used. Maybe we shouldn't care about
1922 the environment of the simulator regarding isatty, but
1923 that's been working before, in the xsim simulator. */
1924 if (arg2 == TARGET_TCGETS && arg1 == 1)
1925 retval = isatty (1) ? 0 : cb_host_to_target_errno (cb, EINVAL);
1927 retval = -cb_host_to_target_errno (cb, EINVAL);
1931 case TARGET_SYS_munmap:
1936 = unmap_pages (sd, ¤t_cpu->highest_mmapped_page, addr,
1938 retval = result != 0 ? -cb_host_to_target_errno (cb, result) : 0;
1942 case TARGET_SYS_wait4:
1950 /* FIXME: We're not properly implementing __WCLONE, and we
1951 don't really need the special casing so we might as well
1952 make this general. */
1953 if ((!(pid == (USI) -1
1954 && options == (TARGET___WCLONE | TARGET_WNOHANG)
1957 && (options == TARGET___WCLONE
1958 || options == TARGET___WALL)))
1960 || current_cpu->thread_data == NULL)
1963 = cris_unknown_syscall (current_cpu, pc,
1964 "Unimplemented wait4 call "
1965 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1966 (unsigned long) arg1,
1967 (unsigned long) arg2,
1968 (unsigned long) arg3,
1969 (unsigned long) arg4);
1973 if (pid == (USI) -1)
1974 for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
1976 if (current_cpu->thread_data[threadno].threadid
1977 == current_cpu->thread_data[i].parent_threadid
1978 && current_cpu->thread_data[i].threadid != 0
1979 && current_cpu->thread_data[i].cpu_context == NULL)
1981 /* A zombied child. Get the exit value and clear the
1982 zombied entry so it will be reused. */
1983 sim_core_write_unaligned_4 (current_cpu, pc, 0, saddr,
1985 ->thread_data[i].exitval);
1987 = current_cpu->thread_data[i].threadid + TARGET_PID;
1988 memset (¤t_cpu->thread_data[i], 0,
1989 sizeof (current_cpu->thread_data[i]));
1995 /* We're waiting for a specific PID. If we don't find
1996 it zombied on this run, rerun the syscall. */
1997 for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
1998 if (pid == current_cpu->thread_data[i].threadid + TARGET_PID
1999 && current_cpu->thread_data[i].cpu_context == NULL)
2002 /* Get the exit value if the caller wants it. */
2003 sim_core_write_unaligned_4 (current_cpu, pc, 0,
2010 = current_cpu->thread_data[i].threadid + TARGET_PID;
2011 memset (¤t_cpu->thread_data[i], 0,
2012 sizeof (current_cpu->thread_data[i]));
2017 sim_pc_set (current_cpu, pc);
2020 retval = -cb_host_to_target_errno (cb, ECHILD);
2025 case TARGET_SYS_rt_sigaction:
2033 __sighandler_t sa_handler;
2034 unsigned long sa_flags;
2035 void (*sa_restorer)(void);
2041 sim_core_write_unaligned_4 (current_cpu, pc, 0, old_sa + 0,
2042 current_cpu->sighandler[signum]);
2043 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 4, 0);
2044 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 8, 0);
2046 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
2047 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 12, 0);
2048 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 16, 0);
2052 USI target_sa_handler
2053 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa);
2055 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 4);
2056 USI target_sa_restorer
2057 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 8);
2058 USI target_sa_mask_low
2059 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 12);
2060 USI target_sa_mask_high
2061 = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 16);
2063 /* We won't interrupt a syscall so we won't restart it,
2064 but a signal(2) call ends up syscalling rt_sigaction
2065 with this flag, so we have to handle it. The
2066 sa_restorer field contains garbage when not
2067 TARGET_SA_RESTORER, so don't look at it. For the
2068 time being, we don't nest sighandlers, so we
2069 ignore the sa_mask, which simplifies things. */
2070 if ((target_sa_flags != 0
2071 && target_sa_flags != TARGET_SA_RESTART
2072 && target_sa_flags != (TARGET_SA_RESTART|TARGET_SA_SIGINFO))
2073 || target_sa_handler == 0)
2076 = cris_unknown_syscall (current_cpu, pc,
2077 "Unimplemented rt_sigaction "
2080 "[0x%x, 0x%x, 0x%x, "
2081 "{0x%x, 0x%x}], 0x%lx)\n",
2082 (unsigned long) arg1,
2083 (unsigned long) arg2,
2088 target_sa_mask_high,
2089 (unsigned long) arg3);
2093 current_cpu->sighandler[signum] = target_sa_handler;
2095 /* Because we may have unblocked signals, one may now be
2096 pending, if there are threads, that is. */
2097 if (current_cpu->thread_data)
2098 current_cpu->thread_data[threadno].sigpending = 1;
2104 case TARGET_SYS_mremap:
2110 USI new_addr = arg5;
2113 if (new_len == old_len)
2114 /* The program and/or library is possibly confused but
2115 this is a valid call. Happens with ipps-1.40 on file
2118 else if (new_len < old_len)
2120 /* Shrinking is easy. */
2121 if (unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
2122 addr + new_len, old_len - new_len) != 0)
2123 retval = -cb_host_to_target_errno (cb, EINVAL);
2127 else if (! is_mapped (sd, ¤t_cpu->highest_mmapped_page,
2128 addr + old_len, new_len - old_len))
2130 /* If the extension isn't mapped, we can just add it. */
2132 = create_map (sd, ¤t_cpu->highest_mmapped_page,
2133 addr + old_len, new_len - old_len);
2135 if (mapped_addr > (USI) -8192)
2136 retval = -cb_host_to_target_errno (cb, -(SI) mapped_addr);
2140 else if (flags & TARGET_MREMAP_MAYMOVE)
2142 /* Create a whole new map and copy the contents
2143 block-by-block there. We ignore the new_addr argument
2146 USI prev_addr = addr;
2147 USI prev_len = old_len;
2150 = create_map (sd, ¤t_cpu->highest_mmapped_page,
2153 if (mapped_addr > (USI) -8192)
2155 retval = -cb_host_to_target_errno (cb, -(SI) new_addr);
2159 retval = mapped_addr;
2162 old_len -= 8192, mapped_addr += 8192, addr += 8192)
2164 if (sim_core_read_buffer (sd, current_cpu, read_map, buf,
2166 || sim_core_write_buffer (sd, current_cpu, 0, buf,
2167 mapped_addr, 8192) != 8192)
2171 if (unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
2172 prev_addr, prev_len) != 0)
2176 retval = -cb_host_to_target_errno (cb, -ENOMEM);
2180 case TARGET_SYS_poll:
2182 int npollfds = arg2;
2198 /* Check that this is the expected poll call from
2199 linuxthreads/manager.c; we don't support anything else.
2200 Remember, fd == 0 isn't supported. */
2202 || ((fd = sim_core_read_unaligned_4 (current_cpu, pc,
2204 || ((events = sim_core_read_unaligned_2 (current_cpu, pc,
2207 || ((cb->to_fstat) (cb, fd, &buf) != 0
2208 || (buf.st_mode & S_IFIFO) == 0)
2209 || current_cpu->thread_data == NULL)
2212 = cris_unknown_syscall (current_cpu, pc,
2213 "Unimplemented poll syscall "
2214 "(0x%lx: [0x%x, 0x%x, x], "
2216 (unsigned long) arg1, fd, events,
2217 (unsigned long) arg2,
2218 (unsigned long) arg3);
2224 /* Iterate over threads; find a marker that a writer is
2225 sleeping, waiting for a reader. */
2226 for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
2227 if (current_cpu->thread_data[i].cpu_context != NULL
2228 && current_cpu->thread_data[i].pipe_read_fd == fd)
2230 revents = TARGET_POLLIN;
2235 /* Timeout decreases with whatever time passed between the
2236 last syscall and this. That's not exactly right for the
2237 first call, but it's close enough that it isn't
2238 worthwhile to complicate matters by making that a special
2241 -= (TARGET_TIME_MS (current_cpu)
2242 - (current_cpu->thread_data[threadno].last_execution));
2244 /* Arrange to repeat this syscall until timeout or event,
2245 decreasing timeout at each iteration. */
2246 if (timeout > 0 && revents == 0)
2248 bfd_byte timeout_buf[4];
2250 bfd_putl32 (timeout, timeout_buf);
2251 (*CPU_REG_STORE (current_cpu)) (current_cpu,
2252 H_GR_R12, timeout_buf, 4);
2253 sim_pc_set (current_cpu, pc);
2258 sim_core_write_unaligned_2 (current_cpu, pc, 0, ufds + 4 + 2,
2263 case TARGET_SYS_time:
2265 retval = (int) (*cb->time) (cb, 0L);
2267 /* At time of this writing, CB_SYSCALL_time doesn't do the
2268 part of setting *arg1 to the return value. */
2270 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, retval);
2274 case TARGET_SYS_gettimeofday:
2277 USI ts = TARGET_TIME (current_cpu);
2278 USI tms = TARGET_TIME_MS (current_cpu);
2280 /* First dword is seconds since TARGET_EPOCH. */
2281 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, ts);
2283 /* Second dword is microseconds. */
2284 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1 + 4,
2285 (tms % 1000) * 1000);
2289 /* Time-zone info is always cleared. */
2290 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, 0);
2291 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, 0);
2296 case TARGET_SYS_llseek:
2298 /* If it fits, tweak parameters to fit the "generic" 32-bit
2299 lseek and use that. */
2307 if (!((offs_hi == 0 && offs_lo >= 0)
2308 || (offs_hi == -1 && offs_lo < 0)))
2311 = cris_unknown_syscall (current_cpu, pc,
2312 "Unimplemented llseek offset,"
2313 " fd %d: 0x%x:0x%x\n",
2314 fd, (unsigned) arg2,
2319 s.func = TARGET_SYS_lseek;
2322 if (cb_syscall (cb, &s) != CB_RC_OK)
2324 sim_io_eprintf (sd, "Break 13: invalid %d? Returned %ld\n", callnum,
2326 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
2329 retval = -s.errcode;
2332 sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp,
2334 sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp + 4,
2335 s.result < 0 ? -1 : 0);
2340 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2343 void *iov_base; Starting address
2344 size_t iov_len; Number of bytes to transfer
2346 case TARGET_SYS_writev:
2354 /* We'll ignore strict error-handling and just do multiple write calls. */
2355 for (i = 0; i < iovcnt; i++)
2359 = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2362 = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2365 s.func = TARGET_SYS_write;
2370 if (cb_syscall (cb, &s) != CB_RC_OK)
2372 sysret = s.result == -1 ? -s.errcode : s.result;
2374 if (sysret != iov_len)
2389 /* This one does have a generic callback function, but at the time
2390 of this writing, cb_syscall does not have code for it, and we
2391 need target-specific code for the threads implementation
2393 case TARGET_SYS_kill:
2400 /* At kill(2), glibc sets signal masks such that the thread
2401 machinery is initialized. Still, there is and was only
2403 if (current_cpu->max_threadid == 0)
2405 if (pid != TARGET_PID)
2407 retval = -cb_host_to_target_errno (cb, EPERM);
2411 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2412 if (sig == TARGET_SIGABRT)
2413 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2414 the end-point for failing GCC test-cases. */
2415 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2419 sim_io_eprintf (sd, "Unimplemented signal: %d\n", sig);
2420 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2424 /* This will not be reached. */
2428 retval = deliver_signal (current_cpu, sig, pid);
2432 case TARGET_SYS_rt_sigprocmask:
2439 if (how != TARGET_SIG_BLOCK
2440 && how != TARGET_SIG_SETMASK
2441 && how != TARGET_SIG_UNBLOCK)
2444 = cris_unknown_syscall (current_cpu, pc,
2445 "Unimplemented rt_sigprocmask "
2446 "syscall (0x%x, 0x%x, 0x%x)\n",
2454 = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2457 = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2460 /* The sigmask is kept in the per-thread data, so we may
2461 need to create the first one. */
2462 if (current_cpu->thread_data == NULL)
2463 make_first_thread (current_cpu);
2465 if (how == TARGET_SIG_SETMASK)
2466 for (i = 0; i < 64; i++)
2467 current_cpu->thread_data[threadno].sigdata[i].blocked = 0;
2469 for (i = 0; i < 32; i++)
2470 if ((set_low & (1 << i)))
2471 current_cpu->thread_data[threadno].sigdata[i + 1].blocked
2472 = (how != TARGET_SIG_UNBLOCK);
2474 for (i = 0; i < 31; i++)
2475 if ((set_high & (1 << i)))
2476 current_cpu->thread_data[threadno].sigdata[i + 33].blocked
2477 = (how != TARGET_SIG_UNBLOCK);
2479 /* The mask changed, so a signal may be unblocked for
2481 current_cpu->thread_data[threadno].sigpending = 1;
2489 for (i = 0; i < 32; i++)
2490 if (current_cpu->thread_data[threadno]
2491 .sigdata[i + 1].blocked)
2493 for (i = 0; i < 31; i++)
2494 if (current_cpu->thread_data[threadno]
2495 .sigdata[i + 33].blocked)
2498 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 0, set_low);
2499 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 4, set_high);
2506 case TARGET_SYS_sigreturn:
2510 int was_sigsuspended;
2512 if (current_cpu->thread_data == NULL
2513 /* The CPU context is saved with the simulator data, not
2514 on the stack as in the real world. */
2515 || (current_cpu->thread_data[threadno].cpu_context_atsignal
2519 = cris_unknown_syscall (current_cpu, pc,
2520 "Invalid sigreturn syscall: "
2521 "no signal handler active "
2522 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2524 (unsigned long) arg1,
2525 (unsigned long) arg2,
2526 (unsigned long) arg3,
2527 (unsigned long) arg4,
2528 (unsigned long) arg5,
2529 (unsigned long) arg6);
2534 = current_cpu->thread_data[threadno].sigsuspended;
2536 /* Restore the sigmask, either from the stack copy made when
2537 the sighandler was called, or from the saved state
2538 specifically for sigsuspend(2). */
2539 if (was_sigsuspended)
2541 current_cpu->thread_data[threadno].sigsuspended = 0;
2542 for (i = 0; i < 64; i++)
2543 current_cpu->thread_data[threadno].sigdata[i].blocked
2544 = current_cpu->thread_data[threadno]
2545 .sigdata[i].blocked_suspendsave;
2553 (*CPU_REG_FETCH (current_cpu)) (current_cpu,
2554 H_GR_SP, regbuf, 4);
2555 sp = bfd_getl32 (regbuf);
2557 = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp);
2559 = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp + 4);
2561 for (i = 0; i < 32; i++)
2562 current_cpu->thread_data[threadno].sigdata[i + 1].blocked
2563 = (set_low & (1 << i)) != 0;
2564 for (i = 0; i < 31; i++)
2565 current_cpu->thread_data[threadno].sigdata[i + 33].blocked
2566 = (set_high & (1 << i)) != 0;
2569 /* The mask changed, so a signal may be unblocked for
2571 current_cpu->thread_data[threadno].sigpending = 1;
2573 memcpy (¤t_cpu->cpu_data_placeholder,
2574 current_cpu->thread_data[threadno].cpu_context_atsignal,
2575 current_cpu->thread_cpu_data_size);
2576 free (current_cpu->thread_data[threadno].cpu_context_atsignal);
2577 current_cpu->thread_data[threadno].cpu_context_atsignal = NULL;
2579 /* The return value must come from the saved R10. */
2580 (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, regbuf, 4);
2581 retval = bfd_getl32 (regbuf);
2583 /* We must also break the "sigsuspension loop". */
2584 if (was_sigsuspended)
2585 sim_pc_set (current_cpu, sim_pc_get (current_cpu) + 2);
2589 case TARGET_SYS_rt_sigsuspend:
2597 = cris_unknown_syscall (current_cpu, pc,
2598 "Unimplemented rt_sigsuspend syscall"
2599 " arguments (0x%lx, 0x%lx)\n",
2600 (unsigned long) arg1,
2601 (unsigned long) arg2);
2605 /* Don't change the signal mask if we're already in
2606 sigsuspend state (i.e. this syscall is a rerun). */
2607 else if (!current_cpu->thread_data[threadno].sigsuspended)
2610 = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2613 = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2617 /* Save the current sigmask and insert the user-supplied
2619 for (i = 0; i < 32; i++)
2621 current_cpu->thread_data[threadno]
2622 .sigdata[i + 1].blocked_suspendsave
2623 = current_cpu->thread_data[threadno]
2624 .sigdata[i + 1].blocked;
2626 current_cpu->thread_data[threadno]
2627 .sigdata[i + 1].blocked = (set_low & (1 << i)) != 0;
2629 for (i = 0; i < 31; i++)
2631 current_cpu->thread_data[threadno]
2632 .sigdata[i + 33].blocked_suspendsave
2633 = current_cpu->thread_data[threadno]
2634 .sigdata[i + 33].blocked;
2635 current_cpu->thread_data[threadno]
2636 .sigdata[i + 33].blocked = (set_high & (1 << i)) != 0;
2639 current_cpu->thread_data[threadno].sigsuspended = 1;
2641 /* The mask changed, so a signal may be unblocked for
2643 current_cpu->thread_data[threadno].sigpending = 1;
2646 /* Because we don't use arg1 (newsetp) when this syscall is
2647 rerun, it doesn't matter that we overwrite it with the
2648 (constant) return value. */
2649 retval = -cb_host_to_target_errno (cb, EINTR);
2650 sim_pc_set (current_cpu, pc);
2654 /* Add case labels here for other syscalls using the 32-bit
2655 "struct stat", provided they have a corresponding simulator
2656 function of course. */
2657 case TARGET_SYS_stat:
2658 case TARGET_SYS_fstat:
2660 /* As long as the infrastructure doesn't cache anything
2661 related to the stat mapping, this trick gets us a dual
2662 "struct stat"-type mapping in the least error-prone way. */
2663 const char *saved_map = cb->stat_map;
2664 CB_TARGET_DEFS_MAP *saved_syscall_map = cb->syscall_map;
2666 cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_stat32_map;
2667 cb->stat_map = stat32_map;
2669 if (cb_syscall (cb, &s) != CB_RC_OK)
2672 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2675 retval = s.result == -1 ? -s.errcode : s.result;
2677 cb->stat_map = saved_map;
2678 cb->syscall_map = saved_syscall_map;
2682 case TARGET_SYS_getcwd:
2687 char *cwd = xmalloc (SIM_PATHMAX);
2688 if (cwd != getcwd (cwd, SIM_PATHMAX))
2691 /* FIXME: When and if we support chdir, we need something
2692 a bit more elaborate. */
2693 if (simulator_sysroot[0] != '\0')
2696 retval = -cb_host_to_target_errno (cb, ERANGE);
2697 if (strlen (cwd) + 1 <= size)
2699 retval = strlen (cwd) + 1;
2700 if (sim_core_write_buffer (sd, current_cpu, 0, cwd,
2702 != (unsigned int) retval)
2703 retval = -cb_host_to_target_errno (cb, EFAULT);
2709 case TARGET_SYS_access:
2713 char *pbuf = xmalloc (SIM_PATHMAX);
2718 if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/')
2720 strcpy (pbuf, simulator_sysroot);
2721 o += strlen (simulator_sysroot);
2724 for (i = 0; i + o < SIM_PATHMAX; i++)
2727 = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i);
2728 if (pbuf[i + o] == 0)
2732 if (i + o == SIM_PATHMAX)
2734 retval = -cb_host_to_target_errno (cb, ENAMETOOLONG);
2738 /* Assert that we don't get calls for files for which we
2739 don't have support. */
2740 if (strncmp (pbuf + strlen (simulator_sysroot),
2743 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2750 if (access (pbuf, hmode) != 0)
2751 retval = -cb_host_to_target_errno (cb, errno);
2759 case TARGET_SYS_readlink:
2764 char *pbuf = xmalloc (SIM_PATHMAX);
2765 char *lbuf = xmalloc (SIM_PATHMAX);
2766 char *lbuf_alloc = lbuf;
2771 if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/')
2773 strcpy (pbuf, simulator_sysroot);
2774 o += strlen (simulator_sysroot);
2777 for (i = 0; i + o < SIM_PATHMAX; i++)
2780 = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i);
2781 if (pbuf[i + o] == 0)
2785 if (i + o == SIM_PATHMAX)
2787 retval = -cb_host_to_target_errno (cb, ENAMETOOLONG);
2791 /* Intervene calls for certain files expected in the target
2792 proc file system. */
2793 if (strcmp (pbuf + strlen (simulator_sysroot),
2794 "/proc/" XSTRING (TARGET_PID) "/exe") == 0)
2797 = (STATE_PROG_ARGV (sd) != NULL
2798 ? *STATE_PROG_ARGV (sd) : NULL);
2800 if (argv0 == NULL || *argv0 == '.')
2803 = cris_unknown_syscall (current_cpu, pc,
2804 "Unimplemented readlink syscall "
2805 "(0x%lx: [\"%s\"], 0x%lx)\n",
2806 (unsigned long) arg1, pbuf,
2807 (unsigned long) arg2);
2810 else if (*argv0 == '/')
2812 if (strncmp (simulator_sysroot, argv0,
2813 strlen (simulator_sysroot)) == 0)
2814 argv0 += strlen (simulator_sysroot);
2816 strcpy (lbuf, argv0);
2817 nchars = strlen (argv0) + 1;
2821 if (getcwd (lbuf, SIM_PATHMAX) != NULL
2822 && strlen (lbuf) + 2 + strlen (argv0) < SIM_PATHMAX)
2824 if (strncmp (simulator_sysroot, lbuf,
2825 strlen (simulator_sysroot)) == 0)
2826 lbuf += strlen (simulator_sysroot);
2829 strcat (lbuf, argv0);
2830 nchars = strlen (lbuf) + 1;
2837 nchars = readlink (pbuf, lbuf, SIM_PATHMAX);
2839 /* We trust that the readlink result returns a *relative*
2840 link, or one already adjusted for the file-path-prefix.
2841 (We can't generally tell the difference, so we go with
2842 the easiest decision; no adjustment.) */
2846 retval = -cb_host_to_target_errno (cb, errno);
2850 if (bufsiz < nchars)
2853 if (sim_core_write_buffer (sd, current_cpu, write_map, lbuf,
2854 buf, nchars) != (unsigned int) nchars)
2855 retval = -cb_host_to_target_errno (cb, EFAULT);
2864 case TARGET_SYS_sched_getscheduler:
2868 /* FIXME: Search (other) existing threads. */
2869 if (pid != 0 && pid != TARGET_PID)
2870 retval = -cb_host_to_target_errno (cb, ESRCH);
2872 retval = TARGET_SCHED_OTHER;
2876 case TARGET_SYS_sched_getparam:
2882 struct sched_param {
2886 if (pid != 0 && pid != TARGET_PID)
2887 retval = -cb_host_to_target_errno (cb, ESRCH);
2890 /* FIXME: Save scheduler setting before threads are
2892 sim_core_write_unaligned_4 (current_cpu, pc, 0, paramp,
2893 current_cpu->thread_data != NULL
2895 ->thread_data[threadno]
2903 case TARGET_SYS_sched_setparam:
2908 if ((pid != 0 && pid != TARGET_PID)
2909 || sim_core_read_unaligned_4 (current_cpu, pc, 0,
2911 retval = -cb_host_to_target_errno (cb, EINVAL);
2917 case TARGET_SYS_sched_setscheduler:
2923 if ((pid != 0 && pid != TARGET_PID)
2924 || policy != TARGET_SCHED_OTHER
2925 || sim_core_read_unaligned_4 (current_cpu, pc, 0,
2927 retval = -cb_host_to_target_errno (cb, EINVAL);
2929 /* FIXME: Save scheduler setting to be read in later
2930 sched_getparam calls. */
2935 case TARGET_SYS_sched_yield:
2936 /* We reschedule to the next thread after a syscall anyway, so
2937 we don't have to do anything here than to set the return
2942 case TARGET_SYS_sched_get_priority_min:
2943 case TARGET_SYS_sched_get_priority_max:
2945 retval = -cb_host_to_target_errno (cb, EINVAL);
2950 case TARGET_SYS_ugetrlimit:
2952 unsigned int curlim, maxlim;
2953 if (arg1 != TARGET_RLIMIT_STACK && arg1 != TARGET_RLIMIT_NOFILE)
2955 retval = -cb_host_to_target_errno (cb, EINVAL);
2961 unsigned long rlim_cur;
2962 unsigned long rlim_max;
2964 if (arg1 == TARGET_RLIMIT_NOFILE)
2966 /* Sadly a very low limit. Better not lie, though. */
2967 maxlim = curlim = MAX_CALLBACK_FDS;
2969 else /* arg1 == TARGET_RLIMIT_STACK */
2971 maxlim = 0xffffffff;
2974 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, curlim);
2975 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, maxlim);
2980 case TARGET_SYS_setrlimit:
2981 if (arg1 != TARGET_RLIMIT_STACK)
2983 retval = -cb_host_to_target_errno (cb, EINVAL);
2986 /* FIXME: Save values for future ugetrlimit calls. */
2990 /* Provide a very limited subset of the sysctl functions, and
2991 abort for the rest. */
2992 case TARGET_SYS__sysctl:
2995 struct __sysctl_args {
3002 unsigned long __unused[4];
3004 SI name = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1);
3005 SI name0 = name == 0
3006 ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name);
3007 SI name1 = name == 0
3008 ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name + 4);
3010 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 4);
3012 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 8);
3014 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 12);
3015 SI oldlen = oldlenp == 0
3016 ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, oldlenp);
3018 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 16);
3020 = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 20);
3022 if (name0 == TARGET_CTL_KERN && name1 == TARGET_CTL_KERN_VERSION)
3024 SI to_write = oldlen < (SI) sizeof (TARGET_UTSNAME)
3025 ? oldlen : (SI) sizeof (TARGET_UTSNAME);
3027 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldlenp,
3028 sizeof (TARGET_UTSNAME));
3030 if (sim_core_write_buffer (sd, current_cpu, write_map,
3031 TARGET_UTSNAME, oldval,
3033 != (unsigned int) to_write)
3034 retval = -cb_host_to_target_errno (cb, EFAULT);
3041 = cris_unknown_syscall (current_cpu, pc,
3042 "Unimplemented _sysctl syscall "
3043 "(0x%lx: [0x%lx, 0x%lx],"
3044 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
3045 (unsigned long) name,
3046 (unsigned long) name0,
3047 (unsigned long) name1,
3048 (unsigned long) nlen,
3049 (unsigned long) oldval,
3050 (unsigned long) oldlenp,
3051 (unsigned long) newval,
3052 (unsigned long) newlen);
3056 case TARGET_SYS_exit:
3058 /* Here for all but the last thread. */
3061 = current_cpu->thread_data[threadno].threadid + TARGET_PID;
3063 = (current_cpu->thread_data[threadno].parent_threadid
3065 int exitsig = current_cpu->thread_data[threadno].exitsig;
3067 /* Any children are now all orphans. */
3068 for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
3069 if (current_cpu->thread_data[i].parent_threadid
3070 == current_cpu->thread_data[threadno].threadid)
3071 /* Make getppid(2) return 1 for them, poor little ones. */
3072 current_cpu->thread_data[i].parent_threadid = -TARGET_PID + 1;
3074 /* Free the cpu context data. When the parent has received
3075 the exit status, we'll clear the entry too. */
3076 free (current_cpu->thread_data[threadno].cpu_context);
3077 current_cpu->thread_data[threadno].cpu_context = NULL;
3078 current_cpu->m1threads--;
3081 sim_io_eprintf (sd, "Thread %d exited with status %d\n",
3083 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
3087 /* Still, we may want to support non-zero exit values. */
3088 current_cpu->thread_data[threadno].exitval = arg1 << 8;
3091 deliver_signal (current_cpu, exitsig, ppid);
3095 case TARGET_SYS_clone:
3097 int nthreads = current_cpu->m1threads + 1;
3098 void *thread_cpu_data;
3099 bfd_byte old_sp_buf[4];
3101 const bfd_byte zeros[4] = { 0, 0, 0, 0 };
3104 /* That's right, the syscall clone arguments are reversed
3105 compared to sys_clone notes in clone(2) and compared to
3106 other Linux ports (i.e. it's the same order as in the
3107 clone(2) libcall). */
3111 if (nthreads == SIM_TARGET_MAX_THREADS)
3113 retval = -cb_host_to_target_errno (cb, EAGAIN);
3117 /* FIXME: Implement the low byte. */
3118 if ((flags & ~TARGET_CSIGNAL) !=
3121 | TARGET_CLONE_FILES
3122 | TARGET_CLONE_SIGHAND)
3126 = cris_unknown_syscall (current_cpu, pc,
3127 "Unimplemented clone syscall "
3129 (unsigned long) arg1,
3130 (unsigned long) arg2);
3134 if (current_cpu->thread_data == NULL)
3135 make_first_thread (current_cpu);
3137 /* The created thread will get the new SP and a cleared R10.
3138 Since it's created out of a copy of the old thread and we
3139 don't have a set-register-function that just take the
3140 cpu_data as a parameter, we set the childs values first,
3141 and write back or overwrite them in the parent after the
3143 (*CPU_REG_FETCH (current_cpu)) (current_cpu,
3144 H_GR_SP, old_sp_buf, 4);
3145 bfd_putl32 (newsp, sp_buf);
3146 (*CPU_REG_STORE (current_cpu)) (current_cpu,
3147 H_GR_SP, sp_buf, 4);
3148 (*CPU_REG_STORE (current_cpu)) (current_cpu,
3149 H_GR_R10, (bfd_byte *) zeros, 4);
3152 ->make_thread_cpu_data) (current_cpu,
3153 ¤t_cpu->cpu_data_placeholder);
3154 (*CPU_REG_STORE (current_cpu)) (current_cpu,
3155 H_GR_SP, old_sp_buf, 4);
3157 retval = ++current_cpu->max_threadid + TARGET_PID;
3159 /* Find an unused slot. After a few threads have been created
3160 and exited, the array is expected to be a bit fragmented.
3161 We don't reuse the first entry, though, that of the
3163 for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
3164 if (current_cpu->thread_data[i].cpu_context == NULL
3165 /* Don't reuse a zombied entry. */
3166 && current_cpu->thread_data[i].threadid == 0)
3169 memcpy (¤t_cpu->thread_data[i],
3170 ¤t_cpu->thread_data[threadno],
3171 sizeof (current_cpu->thread_data[i]));
3172 current_cpu->thread_data[i].cpu_context = thread_cpu_data;
3173 current_cpu->thread_data[i].cpu_context_atsignal = NULL;
3174 current_cpu->thread_data[i].threadid = current_cpu->max_threadid;
3175 current_cpu->thread_data[i].parent_threadid
3176 = current_cpu->thread_data[threadno].threadid;
3177 current_cpu->thread_data[i].pipe_read_fd = 0;
3178 current_cpu->thread_data[i].pipe_write_fd = 0;
3179 current_cpu->thread_data[i].at_syscall = 0;
3180 current_cpu->thread_data[i].sigpending = 0;
3181 current_cpu->thread_data[i].sigsuspended = 0;
3182 current_cpu->thread_data[i].exitsig = flags & TARGET_CSIGNAL;
3183 current_cpu->m1threads = nthreads;
3187 /* Better watch these in case they do something necessary. */
3188 case TARGET_SYS_socketcall:
3189 retval = -cb_host_to_target_errno (cb, ENOSYS);
3192 case TARGET_SYS_set_thread_area:
3193 /* Do the same error check as Linux. */
3196 retval = -cb_host_to_target_errno (cb, EINVAL);
3199 (*current_cpu->set_target_thread_data) (current_cpu, arg1);
3203 unimplemented_syscall:
3206 = cris_unknown_syscall (current_cpu, pc,
3207 "Unimplemented syscall: %d "
3208 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3209 callnum, arg1, arg2, arg3, arg4, arg5,
3214 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
3215 if (callnum == TARGET_SYS_open)
3217 current_cpu->last_open_fd = retval;
3218 current_cpu->last_open_flags = arg2;
3221 current_cpu->last_syscall = callnum;
3223 /* A system call is a rescheduling point. For the time being, we don't
3224 reschedule anywhere else. */
3225 if (current_cpu->m1threads != 0
3226 /* We need to schedule off from an exiting thread that is the
3228 || (current_cpu->thread_data != NULL
3229 && current_cpu->thread_data[threadno].cpu_context == NULL))
3231 bfd_byte retval_buf[4];
3233 current_cpu->thread_data[threadno].last_execution
3234 = TARGET_TIME_MS (current_cpu);
3235 bfd_putl32 (retval, retval_buf);
3236 (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
3238 current_cpu->thread_data[threadno].at_syscall = 1;
3239 reschedule (current_cpu);
3241 (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
3242 retval = bfd_getl32 (retval_buf);
3248 /* Callback from simulator write saying that the pipe at (reader, writer)
3249 is now non-empty (so the writer should wait until the pipe is empty, at
3250 least not write to this or any other pipe). Simplest is to just wait
3251 until the pipe is empty. */
3254 cris_pipe_nonempty (host_callback *cb ATTRIBUTE_UNUSED,
3255 int reader, int writer)
3257 SIM_CPU *cpu = current_cpu_for_cb_callback;
3258 const bfd_byte zeros[4] = { 0, 0, 0, 0 };
3260 /* It's the current thread: we just have to re-run the current
3261 syscall instruction (presumably "break 13") and change the syscall
3262 to the special simulator-wait code. Oh, and set a marker that
3263 we're waiting, so we can disambiguate the special call from a
3266 This function may be called multiple times between cris_pipe_empty,
3267 but we must avoid e.g. decreasing PC every time. Check fd markers
3269 if (cpu->thread_data == NULL)
3271 sim_io_eprintf (CPU_STATE (cpu),
3272 "Terminating simulation due to writing pipe rd:wr %d:%d"
3273 " from one single thread\n", reader, writer);
3274 sim_engine_halt (CPU_STATE (cpu), cpu,
3275 NULL, sim_pc_get (cpu), sim_stopped, SIM_SIGILL);
3277 else if (cpu->thread_data[cpu->threadno].pipe_write_fd == 0)
3279 cpu->thread_data[cpu->threadno].pipe_write_fd = writer;
3280 cpu->thread_data[cpu->threadno].pipe_read_fd = reader;
3281 /* FIXME: We really shouldn't change registers other than R10 in
3282 syscalls (like R9), here or elsewhere. */
3283 (*CPU_REG_STORE (cpu)) (cpu, H_GR_R9, (bfd_byte *) zeros, 4);
3284 sim_pc_set (cpu, sim_pc_get (cpu) - 2);
3288 /* Callback from simulator close or read call saying that the pipe at
3289 (reader, writer) is now empty (so the writer can write again, perhaps
3290 leave a waiting state). If there are bytes remaining, they couldn't be
3291 consumed (perhaps due to the pipe closing). */
3294 cris_pipe_empty (host_callback *cb,
3299 SIM_CPU *cpu = current_cpu_for_cb_callback;
3300 SIM_DESC sd = CPU_STATE (current_cpu_for_cb_callback);
3301 bfd_byte r10_buf[4];
3303 = cb->pipe_buffer[writer].size - cb->pipe_buffer[reader].size;
3305 /* We need to find the thread that waits for this pipe. */
3306 for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
3307 if (cpu->thread_data[i].cpu_context
3308 && cpu->thread_data[i].pipe_write_fd == writer)
3312 /* Temporarily switch to this cpu context, so we can change the
3313 PC by ordinary calls. */
3315 memcpy (cpu->thread_data[cpu->threadno].cpu_context,
3316 &cpu->cpu_data_placeholder,
3317 cpu->thread_cpu_data_size);
3318 memcpy (&cpu->cpu_data_placeholder,
3319 cpu->thread_data[i].cpu_context,
3320 cpu->thread_cpu_data_size);
3322 /* The return value is supposed to contain the number of
3323 written bytes, which is the number of bytes requested and
3324 returned at the write call. You might think the right
3325 thing is to adjust the return-value to be only the
3326 *consumed* number of bytes, but it isn't. We're only
3327 called if the pipe buffer is fully consumed or it is being
3328 closed, possibly with remaining bytes. For the latter
3329 case, the writer is still supposed to see success for
3330 PIPE_BUF bytes (a constant which we happen to know and is
3331 unlikely to change). The return value may also be a
3332 negative number; an error value. This case is covered
3333 because "remaining" is always >= 0. */
3334 (*CPU_REG_FETCH (cpu)) (cpu, H_GR_R10, r10_buf, 4);
3335 retval = (int) bfd_getl_signed_32 (r10_buf);
3336 if (retval - remaining > TARGET_PIPE_BUF)
3338 bfd_putl32 (retval - remaining, r10_buf);
3339 (*CPU_REG_STORE (cpu)) (cpu, H_GR_R10, r10_buf, 4);
3341 sim_pc_set (cpu, sim_pc_get (cpu) + 2);
3342 memcpy (cpu->thread_data[i].cpu_context,
3343 &cpu->cpu_data_placeholder,
3344 cpu->thread_cpu_data_size);
3345 memcpy (&cpu->cpu_data_placeholder,
3346 cpu->thread_data[cpu->threadno].cpu_context,
3347 cpu->thread_cpu_data_size);
3348 cpu->thread_data[i].pipe_read_fd = 0;
3349 cpu->thread_data[i].pipe_write_fd = 0;
3356 /* We have a simulator-specific notion of time. See TARGET_TIME. */
3359 cris_time (host_callback *cb ATTRIBUTE_UNUSED, long *t)
3361 long retval = TARGET_TIME (current_cpu_for_cb_callback);
3367 /* Set target-specific callback data. */
3370 cris_set_callbacks (host_callback *cb)
3372 /* Yeargh, have to cast away constness to avoid warnings. */
3373 cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_map;
3374 cb->errno_map = (CB_TARGET_DEFS_MAP *) errno_map;
3376 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3377 parameter to cb_store_target_endian will make st_size negative.
3378 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3379 *unsigned*, and/or add syntax for signed-ness. */
3380 cb->stat_map = stat_map;
3381 cb->open_map = (CB_TARGET_DEFS_MAP *) open_map;
3382 cb->pipe_nonempty = cris_pipe_nonempty;
3383 cb->pipe_empty = cris_pipe_empty;
3384 cb->time = cris_time;
3387 /* Process an address exception. */
3390 cris_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
3391 unsigned int map, int nr_bytes, address_word addr,
3392 transfer_type transfer, sim_core_signals sig)
3394 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,