1 /* CRIS exception, interrupt, and trap (EIT) support
2 Copyright (C) 2004-2022 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/>. */
20 /* This must come before any other includes. */
23 #include "portability.h"
25 #include "sim-syscall.h"
26 #include "sim-options.h"
27 #include "sim-signal.h"
28 #include "sim/callback.h"
30 /* FIXME: get rid of targ-vals.h usage everywhere else. */
41 #ifdef HAVE_SYS_PARAM_H
42 #include <sys/param.h>
44 #ifdef HAVE_SYS_STAT_H
47 /* For PATH_MAX, originally. */
52 /* From ld/sysdep.h. */
54 # define SIM_PATHMAX PATH_MAX
57 # define SIM_PATHMAX MAXPATHLEN
59 # define SIM_PATHMAX 1024
63 /* The verbatim values are from asm-cris/unistd.h. */
65 #define TARGET_SYS_exit 1
66 #define TARGET_SYS_read 3
67 #define TARGET_SYS_write 4
68 #define TARGET_SYS_open 5
69 #define TARGET_SYS_close 6
70 #define TARGET_SYS_unlink 10
71 #define TARGET_SYS_time 13
72 #define TARGET_SYS_lseek 19
73 #define TARGET_SYS_getpid 20
74 #define TARGET_SYS_access 33
75 #define TARGET_SYS_kill 37
76 #define TARGET_SYS_rename 38
77 #define TARGET_SYS_pipe 42
78 #define TARGET_SYS_brk 45
79 #define TARGET_SYS_ioctl 54
80 #define TARGET_SYS_fcntl 55
81 #define TARGET_SYS_getppid 64
82 #define TARGET_SYS_setrlimit 75
83 #define TARGET_SYS_gettimeofday 78
84 #define TARGET_SYS_readlink 85
85 #define TARGET_SYS_munmap 91
86 #define TARGET_SYS_truncate 92
87 #define TARGET_SYS_ftruncate 93
88 #define TARGET_SYS_socketcall 102
89 #define TARGET_SYS_stat 106
90 #define TARGET_SYS_fstat 108
91 #define TARGET_SYS_wait4 114
92 #define TARGET_SYS_sigreturn 119
93 #define TARGET_SYS_clone 120
94 #define TARGET_SYS_uname 122
95 #define TARGET_SYS_mprotect 125
96 #define TARGET_SYS_llseek 140
97 #define TARGET_SYS_writev 146
98 #define TARGET_SYS__sysctl 149
99 #define TARGET_SYS_sched_setparam 154
100 #define TARGET_SYS_sched_getparam 155
101 #define TARGET_SYS_sched_setscheduler 156
102 #define TARGET_SYS_sched_getscheduler 157
103 #define TARGET_SYS_sched_yield 158
104 #define TARGET_SYS_sched_get_priority_max 159
105 #define TARGET_SYS_sched_get_priority_min 160
106 #define TARGET_SYS_mremap 163
107 #define TARGET_SYS_poll 168
108 #define TARGET_SYS_rt_sigaction 174
109 #define TARGET_SYS_rt_sigprocmask 175
110 #define TARGET_SYS_rt_sigsuspend 179
111 #define TARGET_SYS_getcwd 183
112 #define TARGET_SYS_ugetrlimit 191
113 #define TARGET_SYS_mmap2 192
114 #define TARGET_SYS_stat64 195
115 #define TARGET_SYS_lstat64 196
116 #define TARGET_SYS_fstat64 197
117 #define TARGET_SYS_geteuid32 201
118 #define TARGET_SYS_getuid32 199
119 #define TARGET_SYS_getegid32 202
120 #define TARGET_SYS_getgid32 200
121 #define TARGET_SYS_fcntl64 221
122 #define TARGET_SYS_set_thread_area 243
123 #define TARGET_SYS_exit_group 252
125 #define TARGET_PROT_READ 0x1
126 #define TARGET_PROT_WRITE 0x2
127 #define TARGET_PROT_EXEC 0x4
128 #define TARGET_PROT_NONE 0x0
130 #define TARGET_MAP_SHARED 0x01
131 #define TARGET_MAP_PRIVATE 0x02
132 #define TARGET_MAP_TYPE 0x0f
133 #define TARGET_MAP_FIXED 0x10
134 #define TARGET_MAP_ANONYMOUS 0x20
135 #define TARGET_MAP_DENYWRITE 0x800
137 #define TARGET_CTL_KERN 1
138 #define TARGET_CTL_VM 2
139 #define TARGET_CTL_NET 3
140 #define TARGET_CTL_PROC 4
141 #define TARGET_CTL_FS 5
142 #define TARGET_CTL_DEBUG 6
143 #define TARGET_CTL_DEV 7
144 #define TARGET_CTL_BUS 8
145 #define TARGET_CTL_ABI 9
147 #define TARGET_CTL_KERN_VERSION 4
150 #define TARGET_MREMAP_MAYMOVE 1
151 #define TARGET_MREMAP_FIXED 2
153 #define TARGET_TCGETS 0x5401
155 #define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
157 /* Seconds since 1970-01-01 to the above date + 10 minutes;
158 'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'. */
159 #define TARGET_EPOCH 1230764410
161 /* Milliseconds since start of run. We use the number of syscalls to
162 avoid introducing noise in the execution time. */
163 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
165 /* Seconds as in time(2). */
166 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
168 #define TARGET_SCHED_OTHER 0
170 #define TARGET_RLIMIT_STACK 3
171 #define TARGET_RLIMIT_NOFILE 7
173 #define SIM_TARGET_MAX_THREADS 64
174 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
176 /* From linux/sched.h. */
177 #define TARGET_CSIGNAL 0x000000ff
178 #define TARGET_CLONE_VM 0x00000100
179 #define TARGET_CLONE_FS 0x00000200
180 #define TARGET_CLONE_FILES 0x00000400
181 #define TARGET_CLONE_SIGHAND 0x00000800
182 #define TARGET_CLONE_PID 0x00001000
183 #define TARGET_CLONE_PTRACE 0x00002000
184 #define TARGET_CLONE_VFORK 0x00004000
185 #define TARGET_CLONE_PARENT 0x00008000
186 #define TARGET_CLONE_THREAD 0x00010000
187 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
189 /* From asm-cris/poll.h. */
190 #define TARGET_POLLIN 1
192 /* From asm-cris/signal.h. */
193 #define TARGET_SIG_BLOCK 0
194 #define TARGET_SIG_UNBLOCK 1
195 #define TARGET_SIG_SETMASK 2
197 #define TARGET_SIG_DFL 0
198 #define TARGET_SIG_IGN 1
199 #define TARGET_SIG_ERR ((USI)-1)
201 #define TARGET_SIGHUP 1
202 #define TARGET_SIGINT 2
203 #define TARGET_SIGQUIT 3
204 #define TARGET_SIGILL 4
205 #define TARGET_SIGTRAP 5
206 #define TARGET_SIGABRT 6
207 #define TARGET_SIGIOT 6
208 #define TARGET_SIGBUS 7
209 #define TARGET_SIGFPE 8
210 #define TARGET_SIGKILL 9
211 #define TARGET_SIGUSR1 10
212 #define TARGET_SIGSEGV 11
213 #define TARGET_SIGUSR2 12
214 #define TARGET_SIGPIPE 13
215 #define TARGET_SIGALRM 14
216 #define TARGET_SIGTERM 15
217 #define TARGET_SIGSTKFLT 16
218 #define TARGET_SIGCHLD 17
219 #define TARGET_SIGCONT 18
220 #define TARGET_SIGSTOP 19
221 #define TARGET_SIGTSTP 20
222 #define TARGET_SIGTTIN 21
223 #define TARGET_SIGTTOU 22
224 #define TARGET_SIGURG 23
225 #define TARGET_SIGXCPU 24
226 #define TARGET_SIGXFSZ 25
227 #define TARGET_SIGVTALRM 26
228 #define TARGET_SIGPROF 27
229 #define TARGET_SIGWINCH 28
230 #define TARGET_SIGIO 29
231 #define TARGET_SIGPOLL SIGIO
232 /* Actually commented out in the kernel header. */
233 #define TARGET_SIGLOST 29
234 #define TARGET_SIGPWR 30
235 #define TARGET_SIGSYS 31
237 /* From include/asm-cris/signal.h. */
238 #define TARGET_SA_NOCLDSTOP 0x00000001
239 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
240 #define TARGET_SA_SIGINFO 0x00000004
241 #define TARGET_SA_ONSTACK 0x08000000
242 #define TARGET_SA_RESTART 0x10000000
243 #define TARGET_SA_NODEFER 0x40000000
244 #define TARGET_SA_RESETHAND 0x80000000
245 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
246 #define TARGET_SA_RESTORER 0x04000000
248 /* From linux/wait.h. */
249 #define TARGET_WNOHANG 1
250 #define TARGET_WUNTRACED 2
251 #define TARGET___WNOTHREAD 0x20000000
252 #define TARGET___WALL 0x40000000
253 #define TARGET___WCLONE 0x80000000
255 /* From linux/limits.h. */
256 #define TARGET_PIPE_BUF 4096
259 #define TARGET_R_OK 4
260 #define TARGET_W_OK 2
261 #define TARGET_X_OK 1
262 #define TARGET_F_OK 0
264 static const char stat_map
[] =
265 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
266 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
267 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
270 static const CB_TARGET_DEFS_MAP syscall_map
[] =
272 { "open", CB_SYS_open
, TARGET_SYS_open
},
273 { "close", CB_SYS_close
, TARGET_SYS_close
},
274 { "read", CB_SYS_read
, TARGET_SYS_read
},
275 { "write", CB_SYS_write
, TARGET_SYS_write
},
276 { "lseek", CB_SYS_lseek
, TARGET_SYS_lseek
},
277 { "unlink", CB_SYS_unlink
, TARGET_SYS_unlink
},
278 { "getpid", CB_SYS_getpid
, TARGET_SYS_getpid
},
279 { "fstat", CB_SYS_fstat
, TARGET_SYS_fstat64
},
280 { "lstat", CB_SYS_lstat
, TARGET_SYS_lstat64
},
281 { "stat", CB_SYS_stat
, TARGET_SYS_stat64
},
282 { "pipe", CB_SYS_pipe
, TARGET_SYS_pipe
},
283 { "rename", CB_SYS_rename
, TARGET_SYS_rename
},
284 { "truncate", CB_SYS_truncate
, TARGET_SYS_truncate
},
285 { "ftruncate", CB_SYS_ftruncate
, TARGET_SYS_ftruncate
},
289 /* An older, 32-bit-only stat mapping. */
290 static const char stat32_map
[] =
291 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
292 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
293 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
295 /* Map for calls using the 32-bit struct stat. Primarily used by the
296 newlib Linux mapping. */
297 static const CB_TARGET_DEFS_MAP syscall_stat32_map
[] =
299 { "fstat", CB_SYS_fstat
, TARGET_SYS_fstat
},
300 { "stat", CB_SYS_stat
, TARGET_SYS_stat
},
304 /* Giving the true value for the running sim process will lead to
305 non-time-invariant behavior. */
306 #define TARGET_PID 42
308 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
309 we did, we'd still don't get a register number with the "16" offset. */
310 #define TARGET_SRP_REGNUM (16+11)
312 /* Extracted by applying
313 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
314 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
315 adjusting the synonyms. */
317 static const CB_TARGET_DEFS_MAP errno_map
[] =
320 { "EPERM", EPERM
, 1 },
323 { "ENOENT", ENOENT
, 2 },
326 { "ESRCH", ESRCH
, 3 },
329 { "EINTR", EINTR
, 4 },
335 { "ENXIO", ENXIO
, 6 },
338 { "E2BIG", E2BIG
, 7 },
341 { "ENOEXEC", ENOEXEC
, 8 },
344 { "EBADF", EBADF
, 9 },
347 { "ECHILD", ECHILD
, 10 },
350 { "EAGAIN", EAGAIN
, 11 },
353 { "ENOMEM", ENOMEM
, 12 },
356 { "EACCES", EACCES
, 13 },
359 { "EFAULT", EFAULT
, 14 },
362 { "ENOTBLK", ENOTBLK
, 15 },
365 { "EBUSY", EBUSY
, 16 },
368 { "EEXIST", EEXIST
, 17 },
371 { "EXDEV", EXDEV
, 18 },
374 { "ENODEV", ENODEV
, 19 },
377 { "ENOTDIR", ENOTDIR
, 20 },
380 { "EISDIR", EISDIR
, 21 },
383 { "EINVAL", EINVAL
, 22 },
386 { "ENFILE", ENFILE
, 23 },
389 { "EMFILE", EMFILE
, 24 },
392 { "ENOTTY", ENOTTY
, 25 },
395 { "ETXTBSY", ETXTBSY
, 26 },
398 { "EFBIG", EFBIG
, 27 },
401 { "ENOSPC", ENOSPC
, 28 },
404 { "ESPIPE", ESPIPE
, 29 },
407 { "EROFS", EROFS
, 30 },
410 { "EMLINK", EMLINK
, 31 },
413 { "EPIPE", EPIPE
, 32 },
416 { "EDOM", EDOM
, 33 },
419 { "ERANGE", ERANGE
, 34 },
422 { "EDEADLK", EDEADLK
, 35 },
425 { "ENAMETOOLONG", ENAMETOOLONG
, 36 },
428 { "ENOLCK", ENOLCK
, 37 },
431 { "ENOSYS", ENOSYS
, 38 },
434 { "ENOTEMPTY", ENOTEMPTY
, 39 },
437 { "ELOOP", ELOOP
, 40 },
440 { "EWOULDBLOCK", EWOULDBLOCK
, 11 },
443 { "ENOMSG", ENOMSG
, 42 },
446 { "EIDRM", EIDRM
, 43 },
449 { "ECHRNG", ECHRNG
, 44 },
452 { "EL2NSYNC", EL2NSYNC
, 45 },
455 { "EL3HLT", EL3HLT
, 46 },
458 { "EL3RST", EL3RST
, 47 },
461 { "ELNRNG", ELNRNG
, 48 },
464 { "EUNATCH", EUNATCH
, 49 },
467 { "ENOCSI", ENOCSI
, 50 },
470 { "EL2HLT", EL2HLT
, 51 },
473 { "EBADE", EBADE
, 52 },
476 { "EBADR", EBADR
, 53 },
479 { "EXFULL", EXFULL
, 54 },
482 { "ENOANO", ENOANO
, 55 },
485 { "EBADRQC", EBADRQC
, 56 },
488 { "EBADSLT", EBADSLT
, 57 },
491 { "EDEADLOCK", EDEADLOCK
, 35 },
494 { "EBFONT", EBFONT
, 59 },
497 { "ENOSTR", ENOSTR
, 60 },
500 { "ENODATA", ENODATA
, 61 },
503 { "ETIME", ETIME
, 62 },
506 { "ENOSR", ENOSR
, 63 },
509 { "ENONET", ENONET
, 64 },
512 { "ENOPKG", ENOPKG
, 65 },
515 { "EREMOTE", EREMOTE
, 66 },
518 { "ENOLINK", ENOLINK
, 67 },
521 { "EADV", EADV
, 68 },
524 { "ESRMNT", ESRMNT
, 69 },
527 { "ECOMM", ECOMM
, 70 },
530 { "EPROTO", EPROTO
, 71 },
533 { "EMULTIHOP", EMULTIHOP
, 72 },
536 { "EDOTDOT", EDOTDOT
, 73 },
539 { "EBADMSG", EBADMSG
, 74 },
542 { "EOVERFLOW", EOVERFLOW
, 75 },
545 { "ENOTUNIQ", ENOTUNIQ
, 76 },
548 { "EBADFD", EBADFD
, 77 },
551 { "EREMCHG", EREMCHG
, 78 },
554 { "ELIBACC", ELIBACC
, 79 },
557 { "ELIBBAD", ELIBBAD
, 80 },
560 { "ELIBSCN", ELIBSCN
, 81 },
563 { "ELIBMAX", ELIBMAX
, 82 },
566 { "ELIBEXEC", ELIBEXEC
, 83 },
569 { "EILSEQ", EILSEQ
, 84 },
572 { "ERESTART", ERESTART
, 85 },
575 { "ESTRPIPE", ESTRPIPE
, 86 },
578 { "EUSERS", EUSERS
, 87 },
581 { "ENOTSOCK", ENOTSOCK
, 88 },
584 { "EDESTADDRREQ", EDESTADDRREQ
, 89 },
587 { "EMSGSIZE", EMSGSIZE
, 90 },
590 { "EPROTOTYPE", EPROTOTYPE
, 91 },
593 { "ENOPROTOOPT", ENOPROTOOPT
, 92 },
595 #ifdef EPROTONOSUPPORT
596 { "EPROTONOSUPPORT", EPROTONOSUPPORT
, 93 },
598 #ifdef ESOCKTNOSUPPORT
599 { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT
, 94 },
602 { "EOPNOTSUPP", EOPNOTSUPP
, 95 },
605 { "EPFNOSUPPORT", EPFNOSUPPORT
, 96 },
608 { "EAFNOSUPPORT", EAFNOSUPPORT
, 97 },
611 { "EADDRINUSE", EADDRINUSE
, 98 },
614 { "EADDRNOTAVAIL", EADDRNOTAVAIL
, 99 },
617 { "ENETDOWN", ENETDOWN
, 100 },
620 { "ENETUNREACH", ENETUNREACH
, 101 },
623 { "ENETRESET", ENETRESET
, 102 },
626 { "ECONNABORTED", ECONNABORTED
, 103 },
629 { "ECONNRESET", ECONNRESET
, 104 },
632 { "ENOBUFS", ENOBUFS
, 105 },
635 { "EISCONN", EISCONN
, 106 },
638 { "ENOTCONN", ENOTCONN
, 107 },
641 { "ESHUTDOWN", ESHUTDOWN
, 108 },
644 { "ETOOMANYREFS", ETOOMANYREFS
, 109 },
647 { "ETIMEDOUT", ETIMEDOUT
, 110 },
650 { "ECONNREFUSED", ECONNREFUSED
, 111 },
653 { "EHOSTDOWN", EHOSTDOWN
, 112 },
656 { "EHOSTUNREACH", EHOSTUNREACH
, 113 },
659 { "EALREADY", EALREADY
, 114 },
662 { "EINPROGRESS", EINPROGRESS
, 115 },
665 { "ESTALE", ESTALE
, 116 },
668 { "EUCLEAN", EUCLEAN
, 117 },
671 { "ENOTNAM", ENOTNAM
, 118 },
674 { "ENAVAIL", ENAVAIL
, 119 },
677 { "EISNAM", EISNAM
, 120 },
680 { "EREMOTEIO", EREMOTEIO
, 121 },
683 { "EDQUOT", EDQUOT
, 122 },
686 { "ENOMEDIUM", ENOMEDIUM
, 123 },
689 { "EMEDIUMTYPE", EMEDIUMTYPE
, 124 },
694 /* Extracted by applying
695 perl -ne 'if ($_ =~ /^#define/) { split;
696 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
697 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
698 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
699 installation and removing synonyms and unnecessary items. Don't
700 forget the end-marker. */
702 /* These we treat specially, as they're used in the fcntl F_GETFL
703 syscall. For consistency, open_map is also manually edited to use
705 #define TARGET_O_ACCMODE 0x3
706 #define TARGET_O_RDONLY 0x0
707 #define TARGET_O_WRONLY 0x1
709 static const CB_TARGET_DEFS_MAP open_map
[] = {
711 { "O_ACCMODE", O_ACCMODE
, TARGET_O_ACCMODE
},
714 { "O_RDONLY", O_RDONLY
, TARGET_O_RDONLY
},
717 { "O_WRONLY", O_WRONLY
, TARGET_O_WRONLY
},
720 { "O_RDWR", O_RDWR
, 0x2 },
723 { "O_CREAT", O_CREAT
, 0x40 },
726 { "O_EXCL", O_EXCL
, 0x80 },
729 { "O_NOCTTY", O_NOCTTY
, 0x100 },
732 { "O_TRUNC", O_TRUNC
, 0x200 },
735 { "O_APPEND", O_APPEND
, 0x400 },
738 { "O_NONBLOCK", O_NONBLOCK
, 0x800 },
741 { "O_NDELAY", O_NDELAY
, 0x0 },
744 { "O_SYNC", O_SYNC
, 0x1000 },
747 { "FASYNC", FASYNC
, 0x2000 },
750 { "O_DIRECT", O_DIRECT
, 0x4000 },
753 { "O_LARGEFILE", O_LARGEFILE
, 0x8000 },
756 { "O_DIRECTORY", O_DIRECTORY
, 0x10000 },
759 { "O_NOFOLLOW", O_NOFOLLOW
, 0x20000 },
764 /* Let's be less drastic and more traceable. FIXME: mark as noreturn. */
766 sim_io_error (sd, "simulator unhandled condition at %s:%d", \
767 __FUNCTION__, __LINE__)
769 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
770 static SIM_CPU
*current_cpu_for_cb_callback
;
772 static USI
create_map (SIM_DESC
, struct cris_sim_mmapped_page
**,
774 static USI
unmap_pages (SIM_DESC
, struct cris_sim_mmapped_page
**,
776 static USI
is_mapped (SIM_DESC
, struct cris_sim_mmapped_page
**,
778 static void dump_statistics (SIM_CPU
*current_cpu
);
779 static void make_first_thread (SIM_CPU
*current_cpu
);
781 /* When we risk running self-modified code (as in trampolines), this is
782 called from special-case insns. The silicon CRIS CPU:s have enough
783 cache snooping implemented making this a simulator-only issue. Tests:
784 gcc.c-torture/execute/931002-1.c execution, -O3 -g
785 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
788 cris_flush_simulator_decode_cache (SIM_CPU
*current_cpu
,
789 USI pc ATTRIBUTE_UNUSED
)
791 SIM_DESC sd
= CPU_STATE (current_cpu
);
794 if (USING_SCACHE_P (sd
))
795 scache_flush_cpu (current_cpu
);
799 /* Output statistics at the end of a run. */
801 dump_statistics (SIM_CPU
*current_cpu
)
803 SIM_DESC sd
= CPU_STATE (current_cpu
);
804 CRIS_MISC_PROFILE
*profp
805 = CPU_CRIS_MISC_PROFILE (current_cpu
);
806 unsigned64 total
= profp
->basic_cycle_count
;
808 /* Historically, these messages have gone to stderr, so we'll keep it
809 that way. It's also easier to then tell it from normal program
810 output. FIXME: Add redirect option like "run -e file". */
812 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
813 what's included in the "total" count only. */
814 switch (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
815 & FLAG_CRIS_MISC_PROFILE_ALL
)
817 case FLAG_CRIS_MISC_PROFILE_SIMPLE
:
818 sim_io_eprintf (sd
, "Basic clock cycles, total @: %" PRIu64
"\n", total
);
821 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
822 total
+= profp
->unaligned_mem_dword_count
;
824 "Clock cycles including stall cycles for unaligned "
825 "accesses @: %" PRIu64
"\n",
829 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
831 += (profp
->memsrc_stall_count
832 + profp
->memraw_stall_count
833 + profp
->movemsrc_stall_count
834 + profp
->movemdst_stall_count
835 + profp
->mulsrc_stall_count
836 + profp
->jumpsrc_stall_count
837 + profp
->unaligned_mem_dword_count
);
838 sim_io_eprintf (sd
, "Schedulable clock cycles, total @: %" PRIu64
"\n",
842 case FLAG_CRIS_MISC_PROFILE_ALL
:
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 sim_io_eprintf (sd
, "All accounted clock cycles, total @: %" PRIu64
"\n",
859 sim_engine_abort (sd
, current_cpu
, 0,
860 "Internal inconsistency at %s:%d",
864 /* For v32, unaligned_mem_dword_count should always be 0. For
865 v10, memsrc_stall_count should always be 0. */
866 sim_io_eprintf (sd
, "Memory source stall cycles: %" PRIu64
"\n",
867 profp
->memsrc_stall_count
+ profp
->unaligned_mem_dword_count
);
868 sim_io_eprintf (sd
, "Memory read-after-write stall cycles: %" PRIu64
"\n",
869 profp
->memraw_stall_count
);
870 sim_io_eprintf (sd
, "Movem source stall cycles: %" PRIu64
"\n",
871 profp
->movemsrc_stall_count
);
872 sim_io_eprintf (sd
, "Movem destination stall cycles: %" PRIu64
"\n",
873 profp
->movemdst_stall_count
);
874 sim_io_eprintf (sd
, "Movem address stall cycles: %" PRIu64
"\n",
875 profp
->movemaddr_stall_count
);
876 sim_io_eprintf (sd
, "Multiplication source stall cycles: %" PRIu64
"\n",
877 profp
->mulsrc_stall_count
);
878 sim_io_eprintf (sd
, "Jump source stall cycles: %" PRIu64
"\n",
879 profp
->jumpsrc_stall_count
);
880 sim_io_eprintf (sd
, "Branch misprediction stall cycles: %" PRIu64
"\n",
881 profp
->branch_stall_count
);
882 sim_io_eprintf (sd
, "Jump target stall cycles: %" PRIu64
"\n",
883 profp
->jumptarget_stall_count
);
886 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
887 Return 1 if a overlap detected, 0 otherwise. */
890 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED
,
891 struct cris_sim_mmapped_page
**rootp
,
894 struct cris_sim_mmapped_page
*mapp
;
896 if (len
== 0 || (len
& 8191))
899 /* Iterate over the reverse-address sorted pages until we find a page in
900 or lower than the checked area. */
901 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
902 if (mapp
->addr
< addr
+ len
&& mapp
->addr
>= addr
)
908 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
909 Return 1 if the whole area is mapped, 0 otherwise. */
912 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED
,
913 struct cris_sim_mmapped_page
**rootp
,
916 struct cris_sim_mmapped_page
*mapp
;
918 if (len
== 0 || (len
& 8191))
921 /* Iterate over the reverse-address sorted pages until we find a page
922 lower than the checked area. */
923 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
924 if (addr
== mapp
->addr
&& len
== 8192)
926 else if (addr
+ len
> mapp
->addr
)
932 /* Provide a prototype to silence -Wmissing-prototypes. */
933 void cris_dump_map (SIM_CPU
*current_cpu
);
935 /* Debug helper; to be run from gdb. */
937 cris_dump_map (SIM_CPU
*current_cpu
)
939 struct cris_sim_mmapped_page
*mapp
;
942 for (mapp
= current_cpu
->highest_mmapped_page
,
943 start
= mapp
== NULL
? 0 : mapp
->addr
+ 8192,
944 end
= mapp
== NULL
? 0 : mapp
->addr
+ 8191;
948 if (mapp
->addr
!= start
- 8192)
950 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
951 end
= mapp
->addr
+ 8191;
957 if (current_cpu
->highest_mmapped_page
!= NULL
)
958 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
961 /* Create mmapped memory. ADDR is -1 if any address will do. Caller
962 must make sure that the address isn't already mapped. */
965 create_map (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
968 struct cris_sim_mmapped_page
*mapp
;
969 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
970 USI new_addr
= 0x40000000;
972 if (addr
!= (USI
) -1)
974 else if (*rootp
&& rootp
[0]->addr
>= new_addr
)
975 new_addr
= rootp
[0]->addr
+ 8192;
982 /* Which is better: return an error for this, or just round it up? */
985 /* Do a recursive call for each page in the request. */
986 for (page_addr
= new_addr
; len
!= 0; page_addr
+= 8192, len
-= 8192)
987 if (create_map (sd
, rootp
, page_addr
, 8192) >= (USI
) -8191)
994 mapp
!= NULL
&& mapp
->addr
> new_addr
;
996 higher_prevp
= &mapp
->prev
;
998 /* Assert for consistency that we don't create duplicate maps. */
999 if (is_mapped (sd
, rootp
, new_addr
, len
))
1002 /* Allocate the new page, on the next higher page from the last one
1003 allocated, and link in the new descriptor before previous ones. */
1004 mapp
= malloc (sizeof (*mapp
));
1007 return (USI
) -ENOMEM
;
1009 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1013 mapp
->addr
= new_addr
;
1014 mapp
->prev
= *higher_prevp
;
1015 *higher_prevp
= mapp
;
1020 /* Unmap one or more pages. */
1023 unmap_pages (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
1026 struct cris_sim_mmapped_page
*mapp
;
1027 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
1035 /* Which is better: return an error for this, or just round it up? */
1038 /* Loop backwards to make each call is O(1) over the number of pages
1039 allocated, if we're unmapping from the high end of the pages. */
1040 for (page_addr
= addr
+ len
- 8192;
1043 if (unmap_pages (sd
, rootp
, page_addr
, 8192))
1046 if (unmap_pages (sd
, rootp
, addr
, 8192))
1052 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
> addr
; mapp
= mapp
->prev
)
1053 higher_prevp
= &mapp
->prev
;
1055 if (mapp
== NULL
|| mapp
->addr
!= addr
)
1058 *higher_prevp
= mapp
->prev
;
1059 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1064 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1067 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC vpc
)
1069 SIM_DESC sd
= CPU_STATE (current_cpu
);
1071 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
1075 /* Swap one context for another. */
1078 schedule (SIM_CPU
*current_cpu
, int next
)
1080 /* Need to mark context-switches in the trace output. */
1081 if ((CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1082 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE
))
1083 cris_trace_printf (CPU_STATE (current_cpu
), current_cpu
,
1086 /* Copy the current context (if there is one) to its slot. */
1087 if (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
)
1088 memcpy (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
,
1089 ¤t_cpu
->cpu_data_placeholder
,
1090 current_cpu
->thread_cpu_data_size
);
1092 /* Copy the new context from its slot. */
1093 memcpy (¤t_cpu
->cpu_data_placeholder
,
1094 current_cpu
->thread_data
[next
].cpu_context
,
1095 current_cpu
->thread_cpu_data_size
);
1097 /* Update needed stuff to indicate the new context. */
1098 current_cpu
->threadno
= next
;
1100 /* Handle pending signals. */
1101 if (current_cpu
->thread_data
[next
].sigpending
1102 /* We don't run nested signal handlers. This means that pause(2)
1103 and sigsuspend(2) do not work in sighandlers, but that
1104 shouldn't be too hard a restriction. It also greatly
1105 simplifies the code. */
1106 && current_cpu
->thread_data
[next
].cpu_context_atsignal
== NULL
)
1110 /* See if there's really a pending, non-blocked handler. We don't
1111 queue signals, so just use the first one in ascending order. */
1112 for (sig
= 0; sig
< 64; sig
++)
1113 if (current_cpu
->thread_data
[next
].sigdata
[sig
].pending
1114 && !current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
)
1120 USI pc
= sim_pc_get (current_cpu
);
1122 /* It's simpler to save the CPU context inside the simulator
1123 than on the stack. */
1124 current_cpu
->thread_data
[next
].cpu_context_atsignal
1126 ->make_thread_cpu_data
) (current_cpu
,
1127 current_cpu
->thread_data
[next
]
1130 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1131 sp
= bfd_getl32 (regbuf
);
1133 /* Make sure we have an aligned stack. */
1136 /* Make room for the signal frame, aligned. FIXME: Check that
1137 the memory exists, map it in if absent. (BTW, should also
1138 implement on-access automatic stack allocation). */
1141 /* This isn't the same signal frame as the kernel uses, because
1142 we don't want to bother getting all registers on and off the
1145 /* First, we store the currently blocked signals. */
1147 for (i
= 0; i
< 32; i
++)
1149 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 1].blocked
<< i
;
1150 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
, blocked
);
1152 for (i
= 0; i
< 31; i
++)
1154 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 33].blocked
<< i
;
1155 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
+ 4, blocked
);
1157 /* Then, the actual instructions. This is CPU-specific, but we
1158 use instructions from the common subset for v10 and v32 which
1159 should be safe for the time being but could be parametrized
1161 /* MOVU.W [PC+],R9. */
1162 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 8, 0x9c5f);
1163 /* .WORD TARGET_SYS_sigreturn. */
1164 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 10,
1165 TARGET_SYS_sigreturn
);
1167 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 12, 0xe93d);
1169 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1170 instruction. Still, it doesn't matter because v10 has no
1171 delay slot for BREAK so it will not be executed). */
1172 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 16, 0x05b0);
1174 /* Modify registers to hold the right values for the sighandler
1175 context: updated stackpointer and return address pointing to
1176 the sigreturn stub. */
1177 bfd_putl32 (sp
, regbuf
);
1178 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1179 bfd_putl32 (sp
+ 8, regbuf
);
1180 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, TARGET_SRP_REGNUM
,
1183 current_cpu
->thread_data
[next
].sigdata
[sig
].pending
= 0;
1185 /* Block this signal (for the duration of the sighandler). */
1186 current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
= 1;
1188 sim_pc_set (current_cpu
, current_cpu
->sighandler
[sig
]);
1189 bfd_putl32 (sig
, regbuf
);
1190 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
,
1193 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1194 needed all this for, specifies a SA_SIGINFO call but treats it
1195 like an ordinary sighandler; only the signal number argument is
1196 inspected. To make future need to implement SA_SIGINFO
1197 correctly possible, we set the siginfo argument register to a
1198 magic (hopefully non-address) number. (NB: then, you should
1199 just need to pass the siginfo argument; it seems you probably
1200 don't need to implement the specific rt_sigreturn.) */
1201 bfd_putl32 (0xbad5161f, regbuf
);
1202 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R11
,
1205 /* The third argument is unused and the kernel sets it to 0. */
1206 bfd_putl32 (0, regbuf
);
1207 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R12
,
1212 /* No, there actually was no pending signal for this thread. Reset
1214 current_cpu
->thread_data
[next
].sigpending
= 0;
1218 /* Reschedule the simplest possible way until something else is absolutely
1220 - A. Find the next process (round-robin) that doesn't have at_syscall
1222 - B. If there is none, just run the next process, round-robin.
1223 - Clear at_syscall for the current process. */
1226 reschedule (SIM_CPU
*current_cpu
)
1228 SIM_DESC sd
= CPU_STATE (current_cpu
);
1231 /* Iterate over all thread slots, because after a few thread creations
1232 and exits, we don't know where the live ones are. */
1233 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1234 i
!= current_cpu
->threadno
;
1235 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1236 if (current_cpu
->thread_data
[i
].cpu_context
1237 && current_cpu
->thread_data
[i
].at_syscall
== 0)
1239 schedule (current_cpu
, i
);
1243 /* Pick any next live thread. */
1244 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1245 i
!= current_cpu
->threadno
;
1246 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1247 if (current_cpu
->thread_data
[i
].cpu_context
)
1249 schedule (current_cpu
, i
);
1253 /* More than one live thread, but we couldn't find the next one? */
1257 /* Set up everything to receive (or IGN) an incoming signal to the
1261 deliver_signal (SIM_CPU
*current_cpu
, int sig
, unsigned int pid
)
1264 USI pc
= sim_pc_get (current_cpu
);
1266 /* Find the thread index of the pid. */
1267 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
1268 /* Apparently it's ok to send signals to zombies (so a check for
1269 current_cpu->thread_data[i].cpu_context != NULL would be
1271 if (current_cpu
->thread_data
[i
].threadid
== pid
- TARGET_PID
)
1274 switch (current_cpu
->sighandler
[sig
])
1276 case TARGET_SIG_DFL
:
1279 /* The following according to the glibc
1280 documentation. (The kernel code has non-obvious
1281 execution paths.) */
1284 case TARGET_SIGSEGV
:
1286 case TARGET_SIGABRT
:
1287 case TARGET_SIGTRAP
:
1290 case TARGET_SIGTERM
:
1292 case TARGET_SIGQUIT
:
1293 case TARGET_SIGKILL
:
1296 case TARGET_SIGALRM
:
1297 case TARGET_SIGVTALRM
:
1298 case TARGET_SIGPROF
:
1299 case TARGET_SIGSTOP
:
1301 case TARGET_SIGPIPE
:
1302 case TARGET_SIGLOST
:
1303 case TARGET_SIGXCPU
:
1304 case TARGET_SIGXFSZ
:
1305 case TARGET_SIGUSR1
:
1306 case TARGET_SIGUSR2
:
1307 sim_io_eprintf (CPU_STATE (current_cpu
),
1308 "Exiting pid %d due to signal %d\n",
1310 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1311 NULL
, pc
, sim_stopped
,
1312 sig
== TARGET_SIGABRT
1313 ? SIM_SIGABRT
: SIM_SIGILL
);
1316 /* The default for all other signals is to be ignored. */
1321 case TARGET_SIG_IGN
:
1324 case TARGET_SIGKILL
:
1325 case TARGET_SIGSTOP
:
1326 /* Can't ignore these signals. */
1327 sim_io_eprintf (CPU_STATE (current_cpu
),
1328 "Exiting pid %d due to signal %d\n",
1330 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1331 NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1340 /* Mark the signal as pending, making schedule () check
1341 closer. The signal will be handled when the thread is
1342 scheduled and the signal is unblocked. */
1343 current_cpu
->thread_data
[i
].sigdata
[sig
].pending
= 1;
1344 current_cpu
->thread_data
[i
].sigpending
= 1;
1349 sim_io_eprintf (CPU_STATE (current_cpu
),
1350 "Unimplemented signal: %d\n", sig
);
1351 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
1352 sim_stopped
, SIM_SIGILL
);
1357 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu
)),
1361 /* Make the vector and the first item, the main thread. */
1364 make_first_thread (SIM_CPU
*current_cpu
)
1366 SIM_DESC sd
= CPU_STATE (current_cpu
);
1367 current_cpu
->thread_data
1369 SIM_TARGET_MAX_THREADS
1370 * sizeof (current_cpu
->thread_data
[0]));
1371 current_cpu
->thread_data
[0].cpu_context
1372 = (*current_cpu
->make_thread_cpu_data
) (current_cpu
,
1374 ->cpu_data_placeholder
);
1375 current_cpu
->thread_data
[0].parent_threadid
= -1;
1377 /* For good measure. */
1378 if (TARGET_SIG_DFL
!= 0)
1382 /* Handle unknown system calls. Returns (if it does) the syscall
1386 cris_unknown_syscall (SIM_CPU
*current_cpu
, USI pc
, char *s
, ...)
1388 SIM_DESC sd
= CPU_STATE (current_cpu
);
1389 host_callback
*cb
= STATE_CALLBACK (sd
);
1391 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
1392 || cris_unknown_syscall_action
== CRIS_USYSC_MSG_ENOSYS
)
1397 sim_io_evprintf (sd
, s
, ap
);
1400 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
)
1401 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1404 return -cb_host_to_target_errno (cb
, ENOSYS
);
1407 /* Main function: the handler of the "break 13" syscall insn. */
1410 cris_break_13_handler (SIM_CPU
*current_cpu
, USI callnum
, USI arg1
,
1411 USI arg2
, USI arg3
, USI arg4
, USI arg5
, USI arg6
,
1415 SIM_DESC sd
= CPU_STATE (current_cpu
);
1416 host_callback
*cb
= STATE_CALLBACK (sd
);
1418 int threadno
= current_cpu
->threadno
;
1420 current_cpu
->syscalls
++;
1422 CB_SYSCALL_INIT (&s
);
1428 /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need
1429 to sign-extend the lseek offset to be passed as a signed number,
1430 else we'll truncate it to something > 2GB on hosts where sizeof
1431 long > sizeof USI. We avoid doing it for all syscalls, as arg2 is
1432 e.g. an address for some syscalls. */
1433 if (callnum
== TARGET_SYS_lseek
)
1436 if (callnum
== TARGET_SYS_exit_group
1437 || (callnum
== TARGET_SYS_exit
&& current_cpu
->m1threads
== 0))
1439 if (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1440 & FLAG_CRIS_MISC_PROFILE_ALL
)
1441 dump_statistics (current_cpu
);
1442 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
1446 s
.p2
= (PTR
) current_cpu
;
1447 s
.read_mem
= sim_syscall_read_mem
;
1448 s
.write_mem
= sim_syscall_write_mem
;
1450 current_cpu_for_cb_callback
= current_cpu
;
1452 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1454 sim_engine_abort (sd
, current_cpu
, pc
,
1455 "Break 13: invalid %d? Returned %ld\n", callnum
,
1459 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
1461 if (s
.errcode
!= 0 && s
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
1463 /* If the generic simulator call said ENOSYS, then let's try the
1464 ones we know ourselves.
1466 The convention is to provide *very limited* functionality on an
1467 as-needed basis, only what's covered by the test-suite, tests
1468 added when functionality changes and abort with a descriptive
1469 message for *everything* else. Where there's no test-case, we
1474 /* It's a pretty safe bet that the "old setup() system call"
1475 number will not be re-used; we can't say the same for higher
1476 numbers. We treat this simulator-generated call as "wait
1477 forever"; we re-run this insn. The wait is ended by a
1478 callback. Sanity check that this is the reason we got
1480 if (current_cpu
->thread_data
== NULL
1481 || (current_cpu
->thread_data
[threadno
].pipe_write_fd
== 0))
1482 goto unimplemented_syscall
;
1484 sim_pc_set (current_cpu
, pc
);
1488 case TARGET_SYS_fcntl64
:
1489 case TARGET_SYS_fcntl
:
1494 Glibc checks stdin, stdout and stderr fd:s for
1495 close-on-exec security sanity. We just need to provide a
1496 OK return value. If we really need to have a
1497 close-on-exec flag true, we could just do a real fcntl
1503 /* F_SETFD. Just ignore attempts to set the close-on-exec
1509 /* F_GETFL. Check for the special case for open+fdopen. */
1510 if (current_cpu
->last_syscall
== TARGET_SYS_open
1511 && arg1
== current_cpu
->last_open_fd
)
1513 retval
= current_cpu
->last_open_flags
& TARGET_O_ACCMODE
;
1518 /* Because we can't freopen fd:s 0, 1, 2 to mean
1519 something else than stdin, stdout and stderr
1520 (sim/common/syscall.c:cb_syscall special cases fd
1521 0, 1 and 2), we know what flags that we can
1522 sanely return for these fd:s. */
1523 retval
= TARGET_O_RDONLY
;
1526 else if (arg1
== 1 || arg1
== 2)
1528 retval
= TARGET_O_WRONLY
;
1533 /* Nothing else is implemented. */
1535 = cris_unknown_syscall (current_cpu
, pc
,
1536 "Unimplemented %s syscall "
1537 "(fd: 0x%lx: cmd: 0x%lx arg: "
1539 callnum
== TARGET_SYS_fcntl
1540 ? "fcntl" : "fcntl64",
1541 (unsigned long) (USI
) arg1
,
1542 (unsigned long) (USI
) arg2
,
1543 (unsigned long) (USI
) arg3
);
1548 case TARGET_SYS_uname
:
1550 /* Fill in a few constants to appease glibc. */
1551 static char sim_utsname
[6][65] =
1557 "cris", /* Overwritten below. */
1561 /* Having the hardware type in Linux equal to the bfd
1562 printable name is deliberate: if you make config.guess
1563 work on your Linux-type system the usual way, it
1564 probably will; either the bfd printable_name or the
1565 ambiguous arch_name. */
1566 strcpy (sim_utsname
[4], STATE_ARCHITECTURE (sd
)->printable_name
);
1568 if ((s
.write_mem
) (cb
, &s
, arg1
, (const char *) sim_utsname
,
1569 sizeof (sim_utsname
))
1570 != sizeof (sim_utsname
))
1571 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
1577 case TARGET_SYS_geteuid32
:
1578 /* We tell the truth with these. Maybe we shouldn't, but it
1579 should match the "stat" information. */
1580 retval
= geteuid ();
1583 case TARGET_SYS_getuid32
:
1587 case TARGET_SYS_getegid32
:
1588 retval
= getegid ();
1591 case TARGET_SYS_getgid32
:
1595 case TARGET_SYS_brk
:
1596 /* Most often, we just return the argument, like the Linux
1601 retval
= current_cpu
->endbrk
;
1602 else if (arg1
<= current_cpu
->endmem
)
1603 current_cpu
->endbrk
= arg1
;
1606 USI new_end
= (arg1
+ 8191) & ~8191;
1608 /* If the simulator wants to brk more than a certain very
1609 large amount, something is wrong. FIXME: Return an error
1610 or abort? Have command-line selectable? */
1611 if (new_end
- current_cpu
->endmem
> SIM_MAX_ALLOC_CHUNK
)
1613 current_cpu
->endbrk
= current_cpu
->endmem
;
1614 retval
= current_cpu
->endmem
;
1618 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1619 current_cpu
->endmem
,
1620 new_end
- current_cpu
->endmem
,
1622 current_cpu
->endbrk
= arg1
;
1623 current_cpu
->endmem
= new_end
;
1627 case TARGET_SYS_getpid
:
1628 /* Correct until CLONE_THREAD is implemented. */
1629 retval
= current_cpu
->thread_data
== NULL
1631 : TARGET_PID
+ current_cpu
->thread_data
[threadno
].threadid
;
1634 case TARGET_SYS_getppid
:
1635 /* Correct until CLONE_THREAD is implemented. */
1636 retval
= current_cpu
->thread_data
== NULL
1639 + current_cpu
->thread_data
[threadno
].parent_threadid
);
1642 case TARGET_SYS_mmap2
:
1651 /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1652 still masked away this bit, so let's just ignore
1654 flags
&= ~TARGET_MAP_DENYWRITE
;
1656 /* If the simulator wants to mmap more than the very large
1657 limit, something is wrong. FIXME: Return an error or
1658 abort? Have command-line selectable? */
1659 if (len
> SIM_MAX_ALLOC_CHUNK
)
1661 retval
= -cb_host_to_target_errno (cb
, ENOMEM
);
1665 if ((prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
)
1667 != (TARGET_PROT_READ
1669 | TARGET_PROT_EXEC
))
1670 && (prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
))
1671 && prot
!= TARGET_PROT_READ
)
1672 || (flags
!= (TARGET_MAP_ANONYMOUS
| TARGET_MAP_PRIVATE
)
1673 && flags
!= TARGET_MAP_PRIVATE
1674 && flags
!= (TARGET_MAP_ANONYMOUS
1675 | TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1676 && flags
!= (TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1677 && flags
!= TARGET_MAP_SHARED
)
1679 && prot
!= TARGET_PROT_READ
1680 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1681 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1682 || (fd
== (USI
) -1 && pgoff
!= 0)
1683 || (fd
!= (USI
) -1 && (flags
& TARGET_MAP_ANONYMOUS
)))
1686 = cris_unknown_syscall (current_cpu
, pc
,
1687 "Unimplemented mmap2 call "
1688 "(0x%lx, 0x%lx, 0x%lx, "
1689 "0x%lx, 0x%lx, 0x%lx)\n",
1690 (unsigned long) arg1
,
1691 (unsigned long) arg2
,
1692 (unsigned long) arg3
,
1693 (unsigned long) arg4
,
1694 (unsigned long) arg5
,
1695 (unsigned long) arg6
);
1698 else if (fd
!= (USI
) -1)
1705 /* A non-aligned argument is allowed for files. */
1706 USI newlen
= (len
+ 8191) & ~8191;
1708 /* We only support read, read|exec, and read|write,
1709 which we should already have checked. Check again
1711 if (prot
!= TARGET_PROT_READ
1712 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1713 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1716 if (flags
& TARGET_MAP_FIXED
)
1717 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1719 else if (is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1724 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1725 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1729 if (newaddr
>= (USI
) -8191)
1732 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1736 /* We were asked for MAP_FIXED, but couldn't. */
1737 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1740 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1742 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1746 /* Find the current position in the file. */
1747 s
.func
= TARGET_SYS_lseek
;
1751 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1758 /* Move to the correct offset in the file. */
1759 s
.func
= TARGET_SYS_lseek
;
1761 s
.arg2
= pgoff
*8192;
1763 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1769 /* Use the standard read callback to read in "len"
1771 s
.func
= TARGET_SYS_read
;
1775 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1778 /* If the result is a page or more lesser than what
1779 was requested, something went wrong. */
1780 if (len
>= 8192 && (USI
) s
.result
<= len
- 8192)
1783 /* After reading, we need to go back to the previous
1784 position in the file. */
1785 s
.func
= TARGET_SYS_lseek
;
1789 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1791 if (pos
!= (USI
) s
.result
)
1798 USI newlen
= (len
+ 8191) & ~8191;
1801 if (flags
& TARGET_MAP_FIXED
)
1802 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1804 else if (is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1808 newaddr
= create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1809 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1813 if (newaddr
>= (USI
) -8191)
1814 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1818 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1821 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1823 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1830 case TARGET_SYS_mprotect
:
1832 /* We only cover the case of linuxthreads mprotecting out
1833 its stack guard page and of dynamic loading mprotecting
1834 away the data (for some reason the whole library, then
1835 mprotects away the data part and mmap-FIX:es it again. */
1840 if (prot
!= TARGET_PROT_NONE
1841 || !is_mapped_only (sd
, ¤t_cpu
->highest_mmapped_page
,
1842 addr
, (len
+ 8191) & ~8191))
1845 = cris_unknown_syscall (current_cpu
, pc
,
1846 "Unimplemented mprotect call "
1847 "(0x%lx, 0x%lx, 0x%lx)\n",
1848 (unsigned long) arg1
,
1849 (unsigned long) arg2
,
1850 (unsigned long) arg3
);
1854 /* Just ignore this. We could make this equal to munmap,
1855 but then we'd have to make sure no anon mmaps gets this
1856 address before a subsequent MAP_FIXED mmap intended to
1862 case TARGET_SYS_ioctl
:
1864 /* We support only a very limited functionality: checking
1865 stdout with TCGETS to perform the isatty function. The
1866 TCGETS ioctl isn't actually performed or the result used by
1867 an isatty () caller in a "hello, world" program; only the
1868 return value is then used. Maybe we shouldn't care about
1869 the environment of the simulator regarding isatty, but
1870 that's been working before, in the xsim simulator. */
1871 if (arg2
== TARGET_TCGETS
&& arg1
== 1)
1872 retval
= isatty (1) ? 0 : cb_host_to_target_errno (cb
, EINVAL
);
1874 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1878 case TARGET_SYS_munmap
:
1883 = unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1885 retval
= result
!= 0 ? -cb_host_to_target_errno (cb
, result
) : 0;
1889 case TARGET_SYS_wait4
:
1897 /* FIXME: We're not properly implementing __WCLONE, and we
1898 don't really need the special casing so we might as well
1899 make this general. */
1900 if ((!(pid
== (USI
) -1
1901 && options
== (TARGET___WCLONE
| TARGET_WNOHANG
)
1904 && (options
== TARGET___WCLONE
1905 || options
== TARGET___WALL
)))
1907 || current_cpu
->thread_data
== NULL
)
1910 = cris_unknown_syscall (current_cpu
, pc
,
1911 "Unimplemented wait4 call "
1912 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1913 (unsigned long) arg1
,
1914 (unsigned long) arg2
,
1915 (unsigned long) arg3
,
1916 (unsigned long) arg4
);
1920 if (pid
== (USI
) -1)
1921 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1923 if (current_cpu
->thread_data
[threadno
].threadid
1924 == current_cpu
->thread_data
[i
].parent_threadid
1925 && current_cpu
->thread_data
[i
].threadid
!= 0
1926 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1928 /* A zombied child. Get the exit value and clear the
1929 zombied entry so it will be reused. */
1930 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, saddr
,
1932 ->thread_data
[i
].exitval
);
1934 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1935 memset (¤t_cpu
->thread_data
[i
], 0,
1936 sizeof (current_cpu
->thread_data
[i
]));
1942 /* We're waiting for a specific PID. If we don't find
1943 it zombied on this run, rerun the syscall. */
1944 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1945 if (pid
== current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
1946 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1949 /* Get the exit value if the caller wants it. */
1950 sim_core_write_unaligned_4 (current_cpu
, pc
, 0,
1957 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1958 memset (¤t_cpu
->thread_data
[i
], 0,
1959 sizeof (current_cpu
->thread_data
[i
]));
1964 sim_pc_set (current_cpu
, pc
);
1967 retval
= -cb_host_to_target_errno (cb
, ECHILD
);
1972 case TARGET_SYS_rt_sigaction
:
1980 __sighandler_t sa_handler;
1981 unsigned long sa_flags;
1982 void (*sa_restorer)(void);
1988 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, old_sa
+ 0,
1989 current_cpu
->sighandler
[signum
]);
1990 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 4, 0);
1991 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 8, 0);
1993 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
1994 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 12, 0);
1995 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 16, 0);
1999 USI target_sa_handler
2000 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
);
2002 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 4);
2003 USI target_sa_restorer
2004 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 8);
2005 USI target_sa_mask_low
2006 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 12);
2007 USI target_sa_mask_high
2008 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 16);
2010 /* We won't interrupt a syscall so we won't restart it,
2011 but a signal(2) call ends up syscalling rt_sigaction
2012 with this flag, so we have to handle it. The
2013 sa_restorer field contains garbage when not
2014 TARGET_SA_RESTORER, so don't look at it. For the
2015 time being, we don't nest sighandlers, so we
2016 ignore the sa_mask, which simplifies things. */
2017 if ((target_sa_flags
!= 0
2018 && target_sa_flags
!= TARGET_SA_RESTART
2019 && target_sa_flags
!= (TARGET_SA_RESTART
|TARGET_SA_SIGINFO
))
2020 || target_sa_handler
== 0)
2023 = cris_unknown_syscall (current_cpu
, pc
,
2024 "Unimplemented rt_sigaction "
2027 "[0x%x, 0x%x, 0x%x, "
2028 "{0x%x, 0x%x}], 0x%lx)\n",
2029 (unsigned long) arg1
,
2030 (unsigned long) arg2
,
2035 target_sa_mask_high
,
2036 (unsigned long) arg3
);
2040 current_cpu
->sighandler
[signum
] = target_sa_handler
;
2042 /* Because we may have unblocked signals, one may now be
2043 pending, if there are threads, that is. */
2044 if (current_cpu
->thread_data
)
2045 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2051 case TARGET_SYS_mremap
:
2057 USI new_addr
= arg5
;
2060 if (new_len
== old_len
)
2061 /* The program and/or library is possibly confused but
2062 this is a valid call. Happens with ipps-1.40 on file
2065 else if (new_len
< old_len
)
2067 /* Shrinking is easy. */
2068 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2069 addr
+ new_len
, old_len
- new_len
) != 0)
2070 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2074 else if (! is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
2075 addr
+ old_len
, new_len
- old_len
))
2077 /* If the extension isn't mapped, we can just add it. */
2079 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2080 addr
+ old_len
, new_len
- old_len
);
2082 if (mapped_addr
> (USI
) -8192)
2083 retval
= -cb_host_to_target_errno (cb
, -(SI
) mapped_addr
);
2087 else if (flags
& TARGET_MREMAP_MAYMOVE
)
2089 /* Create a whole new map and copy the contents
2090 block-by-block there. We ignore the new_addr argument
2093 USI prev_addr
= addr
;
2094 USI prev_len
= old_len
;
2097 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2100 if (mapped_addr
> (USI
) -8192)
2102 retval
= -cb_host_to_target_errno (cb
, -(SI
) new_addr
);
2106 retval
= mapped_addr
;
2109 old_len
-= 8192, mapped_addr
+= 8192, addr
+= 8192)
2111 if (sim_core_read_buffer (sd
, current_cpu
, read_map
, buf
,
2113 || sim_core_write_buffer (sd
, current_cpu
, 0, buf
,
2114 mapped_addr
, 8192) != 8192)
2118 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2119 prev_addr
, prev_len
) != 0)
2123 retval
= -cb_host_to_target_errno (cb
, -ENOMEM
);
2127 case TARGET_SYS_poll
:
2129 int npollfds
= arg2
;
2145 /* Check that this is the expected poll call from
2146 linuxthreads/manager.c; we don't support anything else.
2147 Remember, fd == 0 isn't supported. */
2149 || ((fd
= sim_core_read_unaligned_4 (current_cpu
, pc
,
2151 || ((events
= sim_core_read_unaligned_2 (current_cpu
, pc
,
2154 || ((cb
->to_fstat
) (cb
, fd
, &buf
) != 0
2155 || (buf
.st_mode
& S_IFIFO
) == 0)
2156 || current_cpu
->thread_data
== NULL
)
2159 = cris_unknown_syscall (current_cpu
, pc
,
2160 "Unimplemented poll syscall "
2161 "(0x%lx: [0x%x, 0x%x, x], "
2163 (unsigned long) arg1
, fd
, events
,
2164 (unsigned long) arg2
,
2165 (unsigned long) arg3
);
2171 /* Iterate over threads; find a marker that a writer is
2172 sleeping, waiting for a reader. */
2173 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2174 if (current_cpu
->thread_data
[i
].cpu_context
!= NULL
2175 && current_cpu
->thread_data
[i
].pipe_read_fd
== fd
)
2177 revents
= TARGET_POLLIN
;
2182 /* Timeout decreases with whatever time passed between the
2183 last syscall and this. That's not exactly right for the
2184 first call, but it's close enough that it isn't
2185 worthwhile to complicate matters by making that a special
2188 -= (TARGET_TIME_MS (current_cpu
)
2189 - (current_cpu
->thread_data
[threadno
].last_execution
));
2191 /* Arrange to repeat this syscall until timeout or event,
2192 decreasing timeout at each iteration. */
2193 if (timeout
> 0 && revents
== 0)
2195 bfd_byte timeout_buf
[4];
2197 bfd_putl32 (timeout
, timeout_buf
);
2198 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2199 H_GR_R12
, timeout_buf
, 4);
2200 sim_pc_set (current_cpu
, pc
);
2205 sim_core_write_unaligned_2 (current_cpu
, pc
, 0, ufds
+ 4 + 2,
2210 case TARGET_SYS_time
:
2212 retval
= (int) (*cb
->time
) (cb
);
2214 /* At time of this writing, CB_SYSCALL_time doesn't do the
2215 part of setting *arg1 to the return value. */
2217 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, retval
);
2221 case TARGET_SYS_gettimeofday
:
2224 USI ts
= TARGET_TIME (current_cpu
);
2225 USI tms
= TARGET_TIME_MS (current_cpu
);
2227 /* First dword is seconds since TARGET_EPOCH. */
2228 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, ts
);
2230 /* Second dword is microseconds. */
2231 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4,
2232 (tms
% 1000) * 1000);
2236 /* Time-zone info is always cleared. */
2237 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, 0);
2238 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, 0);
2243 case TARGET_SYS_llseek
:
2245 /* If it fits, tweak parameters to fit the "generic" 32-bit
2246 lseek and use that. */
2254 if (!((offs_hi
== 0 && offs_lo
>= 0)
2255 || (offs_hi
== -1 && offs_lo
< 0)))
2258 = cris_unknown_syscall (current_cpu
, pc
,
2259 "Unimplemented llseek offset,"
2260 " fd %d: 0x%x:0x%x\n",
2261 fd
, (unsigned) arg2
,
2266 s
.func
= TARGET_SYS_lseek
;
2269 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2271 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
2273 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2276 retval
= -s
.errcode
;
2279 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
,
2281 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
+ 4,
2282 s
.result
< 0 ? -1 : 0);
2287 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2290 void *iov_base; Starting address
2291 size_t iov_len; Number of bytes to transfer
2293 case TARGET_SYS_writev
:
2301 /* We'll ignore strict error-handling and just do multiple write calls. */
2302 for (i
= 0; i
< iovcnt
; i
++)
2306 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2309 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2312 s
.func
= TARGET_SYS_write
;
2317 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2319 sysret
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2321 if (sysret
!= iov_len
)
2336 /* This one does have a generic callback function, but at the time
2337 of this writing, cb_syscall does not have code for it, and we
2338 need target-specific code for the threads implementation
2340 case TARGET_SYS_kill
:
2347 /* At kill(2), glibc sets signal masks such that the thread
2348 machinery is initialized. Still, there is and was only
2350 if (current_cpu
->max_threadid
== 0)
2352 if (pid
!= TARGET_PID
)
2354 retval
= -cb_host_to_target_errno (cb
, EPERM
);
2358 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2359 if (sig
== TARGET_SIGABRT
)
2360 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2361 the end-point for failing GCC test-cases. */
2362 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2366 sim_io_eprintf (sd
, "Unimplemented signal: %d\n", sig
);
2367 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2371 /* This will not be reached. */
2375 retval
= deliver_signal (current_cpu
, sig
, pid
);
2379 case TARGET_SYS_rt_sigprocmask
:
2386 if (how
!= TARGET_SIG_BLOCK
2387 && how
!= TARGET_SIG_SETMASK
2388 && how
!= TARGET_SIG_UNBLOCK
)
2391 = cris_unknown_syscall (current_cpu
, pc
,
2392 "Unimplemented rt_sigprocmask "
2393 "syscall (0x%x, 0x%x, 0x%x)\n",
2401 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2404 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2407 /* The sigmask is kept in the per-thread data, so we may
2408 need to create the first one. */
2409 if (current_cpu
->thread_data
== NULL
)
2410 make_first_thread (current_cpu
);
2412 if (how
== TARGET_SIG_SETMASK
)
2413 for (i
= 0; i
< 64; i
++)
2414 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
= 0;
2416 for (i
= 0; i
< 32; i
++)
2417 if ((set_low
& (1 << i
)))
2418 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2419 = (how
!= TARGET_SIG_UNBLOCK
);
2421 for (i
= 0; i
< 31; i
++)
2422 if ((set_high
& (1 << i
)))
2423 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2424 = (how
!= TARGET_SIG_UNBLOCK
);
2426 /* The mask changed, so a signal may be unblocked for
2428 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2436 for (i
= 0; i
< 32; i
++)
2437 if (current_cpu
->thread_data
[threadno
]
2438 .sigdata
[i
+ 1].blocked
)
2440 for (i
= 0; i
< 31; i
++)
2441 if (current_cpu
->thread_data
[threadno
]
2442 .sigdata
[i
+ 33].blocked
)
2445 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 0, set_low
);
2446 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 4, set_high
);
2453 case TARGET_SYS_sigreturn
:
2457 int was_sigsuspended
;
2459 if (current_cpu
->thread_data
== NULL
2460 /* The CPU context is saved with the simulator data, not
2461 on the stack as in the real world. */
2462 || (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
2466 = cris_unknown_syscall (current_cpu
, pc
,
2467 "Invalid sigreturn syscall: "
2468 "no signal handler active "
2469 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2471 (unsigned long) arg1
,
2472 (unsigned long) arg2
,
2473 (unsigned long) arg3
,
2474 (unsigned long) arg4
,
2475 (unsigned long) arg5
,
2476 (unsigned long) arg6
);
2481 = current_cpu
->thread_data
[threadno
].sigsuspended
;
2483 /* Restore the sigmask, either from the stack copy made when
2484 the sighandler was called, or from the saved state
2485 specifically for sigsuspend(2). */
2486 if (was_sigsuspended
)
2488 current_cpu
->thread_data
[threadno
].sigsuspended
= 0;
2489 for (i
= 0; i
< 64; i
++)
2490 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
2491 = current_cpu
->thread_data
[threadno
]
2492 .sigdata
[i
].blocked_suspendsave
;
2500 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2501 H_GR_SP
, regbuf
, 4);
2502 sp
= bfd_getl32 (regbuf
);
2504 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
);
2506 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
+ 4);
2508 for (i
= 0; i
< 32; i
++)
2509 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2510 = (set_low
& (1 << i
)) != 0;
2511 for (i
= 0; i
< 31; i
++)
2512 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2513 = (set_high
& (1 << i
)) != 0;
2516 /* The mask changed, so a signal may be unblocked for
2518 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2520 memcpy (¤t_cpu
->cpu_data_placeholder
,
2521 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
,
2522 current_cpu
->thread_cpu_data_size
);
2523 free (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
);
2524 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
= NULL
;
2526 /* The return value must come from the saved R10. */
2527 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, regbuf
, 4);
2528 retval
= bfd_getl32 (regbuf
);
2530 /* We must also break the "sigsuspension loop". */
2531 if (was_sigsuspended
)
2532 sim_pc_set (current_cpu
, sim_pc_get (current_cpu
) + 2);
2536 case TARGET_SYS_rt_sigsuspend
:
2544 = cris_unknown_syscall (current_cpu
, pc
,
2545 "Unimplemented rt_sigsuspend syscall"
2546 " arguments (0x%lx, 0x%lx)\n",
2547 (unsigned long) arg1
,
2548 (unsigned long) arg2
);
2552 /* Don't change the signal mask if we're already in
2553 sigsuspend state (i.e. this syscall is a rerun). */
2554 else if (!current_cpu
->thread_data
[threadno
].sigsuspended
)
2557 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2560 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2564 /* Save the current sigmask and insert the user-supplied
2566 for (i
= 0; i
< 32; i
++)
2568 current_cpu
->thread_data
[threadno
]
2569 .sigdata
[i
+ 1].blocked_suspendsave
2570 = current_cpu
->thread_data
[threadno
]
2571 .sigdata
[i
+ 1].blocked
;
2573 current_cpu
->thread_data
[threadno
]
2574 .sigdata
[i
+ 1].blocked
= (set_low
& (1 << i
)) != 0;
2576 for (i
= 0; i
< 31; i
++)
2578 current_cpu
->thread_data
[threadno
]
2579 .sigdata
[i
+ 33].blocked_suspendsave
2580 = current_cpu
->thread_data
[threadno
]
2581 .sigdata
[i
+ 33].blocked
;
2582 current_cpu
->thread_data
[threadno
]
2583 .sigdata
[i
+ 33].blocked
= (set_high
& (1 << i
)) != 0;
2586 current_cpu
->thread_data
[threadno
].sigsuspended
= 1;
2588 /* The mask changed, so a signal may be unblocked for
2590 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2593 /* Because we don't use arg1 (newsetp) when this syscall is
2594 rerun, it doesn't matter that we overwrite it with the
2595 (constant) return value. */
2596 retval
= -cb_host_to_target_errno (cb
, EINTR
);
2597 sim_pc_set (current_cpu
, pc
);
2601 /* Add case labels here for other syscalls using the 32-bit
2602 "struct stat", provided they have a corresponding simulator
2603 function of course. */
2604 case TARGET_SYS_stat
:
2605 case TARGET_SYS_fstat
:
2607 /* As long as the infrastructure doesn't cache anything
2608 related to the stat mapping, this trick gets us a dual
2609 "struct stat"-type mapping in the least error-prone way. */
2610 const char *saved_map
= cb
->stat_map
;
2611 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
2613 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_stat32_map
;
2614 cb
->stat_map
= stat32_map
;
2616 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2619 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2622 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2624 cb
->stat_map
= saved_map
;
2625 cb
->syscall_map
= saved_syscall_map
;
2629 case TARGET_SYS_getcwd
:
2634 char *cwd
= xmalloc (SIM_PATHMAX
);
2635 if (cwd
!= getcwd (cwd
, SIM_PATHMAX
))
2638 /* FIXME: When and if we support chdir, we need something
2639 a bit more elaborate. */
2640 if (simulator_sysroot
[0] != '\0')
2643 retval
= -cb_host_to_target_errno (cb
, ERANGE
);
2644 if (strlen (cwd
) + 1 <= size
)
2646 retval
= strlen (cwd
) + 1;
2647 if (sim_core_write_buffer (sd
, current_cpu
, 0, cwd
,
2649 != (unsigned int) retval
)
2650 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2656 case TARGET_SYS_access
:
2660 char *pbuf
= xmalloc (SIM_PATHMAX
);
2665 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2667 strcpy (pbuf
, simulator_sysroot
);
2668 o
+= strlen (simulator_sysroot
);
2671 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2674 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2675 if (pbuf
[i
+ o
] == 0)
2679 if (i
+ o
== SIM_PATHMAX
)
2681 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2685 /* Assert that we don't get calls for files for which we
2686 don't have support. */
2687 if (strncmp (pbuf
+ strlen (simulator_sysroot
),
2690 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2697 if (access (pbuf
, hmode
) != 0)
2698 retval
= -cb_host_to_target_errno (cb
, errno
);
2706 case TARGET_SYS_readlink
:
2711 char *pbuf
= xmalloc (SIM_PATHMAX
);
2712 char *lbuf
= xmalloc (SIM_PATHMAX
);
2713 char *lbuf_alloc
= lbuf
;
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 /* Intervene calls for certain files expected in the target
2739 proc file system. */
2740 if (strcmp (pbuf
+ strlen (simulator_sysroot
),
2741 "/proc/" XSTRING (TARGET_PID
) "/exe") == 0)
2744 = (STATE_PROG_ARGV (sd
) != NULL
2745 ? *STATE_PROG_ARGV (sd
) : NULL
);
2747 if (argv0
== NULL
|| *argv0
== '.')
2750 = cris_unknown_syscall (current_cpu
, pc
,
2751 "Unimplemented readlink syscall "
2752 "(0x%lx: [\"%s\"], 0x%lx)\n",
2753 (unsigned long) arg1
, pbuf
,
2754 (unsigned long) arg2
);
2757 else if (*argv0
== '/')
2759 if (strncmp (simulator_sysroot
, argv0
,
2760 strlen (simulator_sysroot
)) == 0)
2761 argv0
+= strlen (simulator_sysroot
);
2763 strcpy (lbuf
, argv0
);
2764 nchars
= strlen (argv0
) + 1;
2768 if (getcwd (lbuf
, SIM_PATHMAX
) != NULL
2769 && strlen (lbuf
) + 2 + strlen (argv0
) < SIM_PATHMAX
)
2771 if (strncmp (simulator_sysroot
, lbuf
,
2772 strlen (simulator_sysroot
)) == 0)
2773 lbuf
+= strlen (simulator_sysroot
);
2776 strcat (lbuf
, argv0
);
2777 nchars
= strlen (lbuf
) + 1;
2784 nchars
= readlink (pbuf
, lbuf
, SIM_PATHMAX
);
2786 /* We trust that the readlink result returns a *relative*
2787 link, or one already adjusted for the file-path-prefix.
2788 (We can't generally tell the difference, so we go with
2789 the easiest decision; no adjustment.) */
2793 retval
= -cb_host_to_target_errno (cb
, errno
);
2797 if (bufsiz
< nchars
)
2800 if (sim_core_write_buffer (sd
, current_cpu
, write_map
, lbuf
,
2801 buf
, nchars
) != (unsigned int) nchars
)
2802 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2811 case TARGET_SYS_sched_getscheduler
:
2815 /* FIXME: Search (other) existing threads. */
2816 if (pid
!= 0 && pid
!= TARGET_PID
)
2817 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2819 retval
= TARGET_SCHED_OTHER
;
2823 case TARGET_SYS_sched_getparam
:
2829 struct sched_param {
2833 if (pid
!= 0 && pid
!= TARGET_PID
)
2834 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2837 /* FIXME: Save scheduler setting before threads are
2839 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, paramp
,
2840 current_cpu
->thread_data
!= NULL
2842 ->thread_data
[threadno
]
2850 case TARGET_SYS_sched_setparam
:
2855 if ((pid
!= 0 && pid
!= TARGET_PID
)
2856 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2858 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2864 case TARGET_SYS_sched_setscheduler
:
2870 if ((pid
!= 0 && pid
!= TARGET_PID
)
2871 || policy
!= TARGET_SCHED_OTHER
2872 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2874 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2876 /* FIXME: Save scheduler setting to be read in later
2877 sched_getparam calls. */
2882 case TARGET_SYS_sched_yield
:
2883 /* We reschedule to the next thread after a syscall anyway, so
2884 we don't have to do anything here than to set the return
2889 case TARGET_SYS_sched_get_priority_min
:
2890 case TARGET_SYS_sched_get_priority_max
:
2892 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2897 case TARGET_SYS_ugetrlimit
:
2899 unsigned int curlim
, maxlim
;
2900 if (arg1
!= TARGET_RLIMIT_STACK
&& arg1
!= TARGET_RLIMIT_NOFILE
)
2902 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2908 unsigned long rlim_cur;
2909 unsigned long rlim_max;
2911 if (arg1
== TARGET_RLIMIT_NOFILE
)
2913 /* Sadly a very low limit. Better not lie, though. */
2914 maxlim
= curlim
= MAX_CALLBACK_FDS
;
2916 else /* arg1 == TARGET_RLIMIT_STACK */
2918 maxlim
= 0xffffffff;
2921 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, curlim
);
2922 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, maxlim
);
2927 case TARGET_SYS_setrlimit
:
2928 if (arg1
!= TARGET_RLIMIT_STACK
)
2930 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2933 /* FIXME: Save values for future ugetrlimit calls. */
2937 /* Provide a very limited subset of the sysctl functions, and
2938 abort for the rest. */
2939 case TARGET_SYS__sysctl
:
2942 struct __sysctl_args {
2949 unsigned long __unused[4];
2951 SI name
= sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
);
2952 SI name0
= name
== 0
2953 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
);
2954 SI name1
= name
== 0
2955 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
+ 4);
2957 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4);
2959 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 8);
2961 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 12);
2962 SI oldlen
= oldlenp
== 0
2963 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, oldlenp
);
2965 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 16);
2967 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 20);
2969 if (name0
== TARGET_CTL_KERN
&& name1
== TARGET_CTL_KERN_VERSION
)
2971 SI to_write
= oldlen
< (SI
) sizeof (TARGET_UTSNAME
)
2972 ? oldlen
: (SI
) sizeof (TARGET_UTSNAME
);
2974 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldlenp
,
2975 sizeof (TARGET_UTSNAME
));
2977 if (sim_core_write_buffer (sd
, current_cpu
, write_map
,
2978 TARGET_UTSNAME
, oldval
,
2980 != (unsigned int) to_write
)
2981 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2988 = cris_unknown_syscall (current_cpu
, pc
,
2989 "Unimplemented _sysctl syscall "
2990 "(0x%lx: [0x%lx, 0x%lx],"
2991 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
2992 (unsigned long) name
,
2993 (unsigned long) name0
,
2994 (unsigned long) name1
,
2995 (unsigned long) nlen
,
2996 (unsigned long) oldval
,
2997 (unsigned long) oldlenp
,
2998 (unsigned long) newval
,
2999 (unsigned long) newlen
);
3003 case TARGET_SYS_exit
:
3005 /* Here for all but the last thread. */
3008 = current_cpu
->thread_data
[threadno
].threadid
+ TARGET_PID
;
3010 = (current_cpu
->thread_data
[threadno
].parent_threadid
3012 int exitsig
= current_cpu
->thread_data
[threadno
].exitsig
;
3014 /* Any children are now all orphans. */
3015 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3016 if (current_cpu
->thread_data
[i
].parent_threadid
3017 == current_cpu
->thread_data
[threadno
].threadid
)
3018 /* Make getppid(2) return 1 for them, poor little ones. */
3019 current_cpu
->thread_data
[i
].parent_threadid
= -TARGET_PID
+ 1;
3021 /* Free the cpu context data. When the parent has received
3022 the exit status, we'll clear the entry too. */
3023 free (current_cpu
->thread_data
[threadno
].cpu_context
);
3024 current_cpu
->thread_data
[threadno
].cpu_context
= NULL
;
3025 current_cpu
->m1threads
--;
3028 sim_io_eprintf (sd
, "Thread %d exited with status %d\n",
3030 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
3034 /* Still, we may want to support non-zero exit values. */
3035 current_cpu
->thread_data
[threadno
].exitval
= arg1
<< 8;
3038 deliver_signal (current_cpu
, exitsig
, ppid
);
3042 case TARGET_SYS_clone
:
3044 int nthreads
= current_cpu
->m1threads
+ 1;
3045 void *thread_cpu_data
;
3046 bfd_byte old_sp_buf
[4];
3048 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3051 /* That's right, the syscall clone arguments are reversed
3052 compared to sys_clone notes in clone(2) and compared to
3053 other Linux ports (i.e. it's the same order as in the
3054 clone(2) libcall). */
3058 if (nthreads
== SIM_TARGET_MAX_THREADS
)
3060 retval
= -cb_host_to_target_errno (cb
, EAGAIN
);
3064 /* FIXME: Implement the low byte. */
3065 if ((flags
& ~TARGET_CSIGNAL
) !=
3068 | TARGET_CLONE_FILES
3069 | TARGET_CLONE_SIGHAND
)
3073 = cris_unknown_syscall (current_cpu
, pc
,
3074 "Unimplemented clone syscall "
3076 (unsigned long) arg1
,
3077 (unsigned long) arg2
);
3081 if (current_cpu
->thread_data
== NULL
)
3082 make_first_thread (current_cpu
);
3084 /* The created thread will get the new SP and a cleared R10.
3085 Since it's created out of a copy of the old thread and we
3086 don't have a set-register-function that just take the
3087 cpu_data as a parameter, we set the childs values first,
3088 and write back or overwrite them in the parent after the
3090 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
3091 H_GR_SP
, old_sp_buf
, 4);
3092 bfd_putl32 (newsp
, sp_buf
);
3093 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3094 H_GR_SP
, sp_buf
, 4);
3095 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3096 H_GR_R10
, (bfd_byte
*) zeros
, 4);
3099 ->make_thread_cpu_data
) (current_cpu
,
3100 ¤t_cpu
->cpu_data_placeholder
);
3101 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3102 H_GR_SP
, old_sp_buf
, 4);
3104 retval
= ++current_cpu
->max_threadid
+ TARGET_PID
;
3106 /* Find an unused slot. After a few threads have been created
3107 and exited, the array is expected to be a bit fragmented.
3108 We don't reuse the first entry, though, that of the
3110 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
3111 if (current_cpu
->thread_data
[i
].cpu_context
== NULL
3112 /* Don't reuse a zombied entry. */
3113 && current_cpu
->thread_data
[i
].threadid
== 0)
3116 memcpy (¤t_cpu
->thread_data
[i
],
3117 ¤t_cpu
->thread_data
[threadno
],
3118 sizeof (current_cpu
->thread_data
[i
]));
3119 current_cpu
->thread_data
[i
].cpu_context
= thread_cpu_data
;
3120 current_cpu
->thread_data
[i
].cpu_context_atsignal
= NULL
;
3121 current_cpu
->thread_data
[i
].threadid
= current_cpu
->max_threadid
;
3122 current_cpu
->thread_data
[i
].parent_threadid
3123 = current_cpu
->thread_data
[threadno
].threadid
;
3124 current_cpu
->thread_data
[i
].pipe_read_fd
= 0;
3125 current_cpu
->thread_data
[i
].pipe_write_fd
= 0;
3126 current_cpu
->thread_data
[i
].at_syscall
= 0;
3127 current_cpu
->thread_data
[i
].sigpending
= 0;
3128 current_cpu
->thread_data
[i
].sigsuspended
= 0;
3129 current_cpu
->thread_data
[i
].exitsig
= flags
& TARGET_CSIGNAL
;
3130 current_cpu
->m1threads
= nthreads
;
3134 /* Better watch these in case they do something necessary. */
3135 case TARGET_SYS_socketcall
:
3136 retval
= -cb_host_to_target_errno (cb
, ENOSYS
);
3139 case TARGET_SYS_set_thread_area
:
3140 /* Do the same error check as Linux. */
3143 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
3146 (*current_cpu
->set_target_thread_data
) (current_cpu
, arg1
);
3150 unimplemented_syscall
:
3153 = cris_unknown_syscall (current_cpu
, pc
,
3154 "Unimplemented syscall: %d "
3155 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3156 callnum
, arg1
, arg2
, arg3
, arg4
, arg5
,
3161 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
3162 if (callnum
== TARGET_SYS_open
)
3164 current_cpu
->last_open_fd
= retval
;
3165 current_cpu
->last_open_flags
= arg2
;
3168 current_cpu
->last_syscall
= callnum
;
3170 /* A system call is a rescheduling point. For the time being, we don't
3171 reschedule anywhere else. */
3172 if (current_cpu
->m1threads
!= 0
3173 /* We need to schedule off from an exiting thread that is the
3175 || (current_cpu
->thread_data
!= NULL
3176 && current_cpu
->thread_data
[threadno
].cpu_context
== NULL
))
3178 bfd_byte retval_buf
[4];
3180 current_cpu
->thread_data
[threadno
].last_execution
3181 = TARGET_TIME_MS (current_cpu
);
3182 bfd_putl32 (retval
, retval_buf
);
3183 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3185 current_cpu
->thread_data
[threadno
].at_syscall
= 1;
3186 reschedule (current_cpu
);
3188 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3189 retval
= bfd_getl32 (retval_buf
);
3195 /* Callback from simulator write saying that the pipe at (reader, writer)
3196 is now non-empty (so the writer should wait until the pipe is empty, at
3197 least not write to this or any other pipe). Simplest is to just wait
3198 until the pipe is empty. */
3201 cris_pipe_nonempty (host_callback
*cb ATTRIBUTE_UNUSED
,
3202 int reader
, int writer
)
3204 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3205 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3207 /* It's the current thread: we just have to re-run the current
3208 syscall instruction (presumably "break 13") and change the syscall
3209 to the special simulator-wait code. Oh, and set a marker that
3210 we're waiting, so we can disambiguate the special call from a
3213 This function may be called multiple times between cris_pipe_empty,
3214 but we must avoid e.g. decreasing PC every time. Check fd markers
3216 if (cpu
->thread_data
== NULL
)
3218 sim_io_eprintf (CPU_STATE (cpu
),
3219 "Terminating simulation due to writing pipe rd:wr %d:%d"
3220 " from one single thread\n", reader
, writer
);
3221 sim_engine_halt (CPU_STATE (cpu
), cpu
,
3222 NULL
, sim_pc_get (cpu
), sim_stopped
, SIM_SIGILL
);
3224 else if (cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
== 0)
3226 cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
= writer
;
3227 cpu
->thread_data
[cpu
->threadno
].pipe_read_fd
= reader
;
3228 /* FIXME: We really shouldn't change registers other than R10 in
3229 syscalls (like R9), here or elsewhere. */
3230 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R9
, (bfd_byte
*) zeros
, 4);
3231 sim_pc_set (cpu
, sim_pc_get (cpu
) - 2);
3235 /* Callback from simulator close or read call saying that the pipe at
3236 (reader, writer) is now empty (so the writer can write again, perhaps
3237 leave a waiting state). If there are bytes remaining, they couldn't be
3238 consumed (perhaps due to the pipe closing). */
3241 cris_pipe_empty (host_callback
*cb
,
3246 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3247 SIM_DESC sd
= CPU_STATE (current_cpu_for_cb_callback
);
3248 bfd_byte r10_buf
[4];
3250 = cb
->pipe_buffer
[writer
].size
- cb
->pipe_buffer
[reader
].size
;
3252 /* We need to find the thread that waits for this pipe. */
3253 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3254 if (cpu
->thread_data
[i
].cpu_context
3255 && cpu
->thread_data
[i
].pipe_write_fd
== writer
)
3259 /* Temporarily switch to this cpu context, so we can change the
3260 PC by ordinary calls. */
3262 memcpy (cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3263 &cpu
->cpu_data_placeholder
,
3264 cpu
->thread_cpu_data_size
);
3265 memcpy (&cpu
->cpu_data_placeholder
,
3266 cpu
->thread_data
[i
].cpu_context
,
3267 cpu
->thread_cpu_data_size
);
3269 /* The return value is supposed to contain the number of
3270 written bytes, which is the number of bytes requested and
3271 returned at the write call. You might think the right
3272 thing is to adjust the return-value to be only the
3273 *consumed* number of bytes, but it isn't. We're only
3274 called if the pipe buffer is fully consumed or it is being
3275 closed, possibly with remaining bytes. For the latter
3276 case, the writer is still supposed to see success for
3277 PIPE_BUF bytes (a constant which we happen to know and is
3278 unlikely to change). The return value may also be a
3279 negative number; an error value. This case is covered
3280 because "remaining" is always >= 0. */
3281 (*CPU_REG_FETCH (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3282 retval
= (int) bfd_getl_signed_32 (r10_buf
);
3283 if (retval
- remaining
> TARGET_PIPE_BUF
)
3285 bfd_putl32 (retval
- remaining
, r10_buf
);
3286 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3288 sim_pc_set (cpu
, sim_pc_get (cpu
) + 2);
3289 memcpy (cpu
->thread_data
[i
].cpu_context
,
3290 &cpu
->cpu_data_placeholder
,
3291 cpu
->thread_cpu_data_size
);
3292 memcpy (&cpu
->cpu_data_placeholder
,
3293 cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3294 cpu
->thread_cpu_data_size
);
3295 cpu
->thread_data
[i
].pipe_read_fd
= 0;
3296 cpu
->thread_data
[i
].pipe_write_fd
= 0;
3303 /* We have a simulator-specific notion of time. See TARGET_TIME. */
3306 cris_time (host_callback
*cb ATTRIBUTE_UNUSED
)
3308 return TARGET_TIME (current_cpu_for_cb_callback
);
3312 cris_getpid (host_callback
*cb ATTRIBUTE_UNUSED
)
3317 /* Set target-specific callback data. */
3320 cris_set_callbacks (host_callback
*cb
)
3322 /* Yeargh, have to cast away constness to avoid warnings. */
3323 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_map
;
3324 cb
->errno_map
= (CB_TARGET_DEFS_MAP
*) errno_map
;
3326 cb
->getpid
= cris_getpid
;
3328 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3329 parameter to cb_store_target_endian will make st_size negative.
3330 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3331 *unsigned*, and/or add syntax for signed-ness. */
3332 cb
->stat_map
= stat_map
;
3333 cb
->open_map
= (CB_TARGET_DEFS_MAP
*) open_map
;
3334 cb
->pipe_nonempty
= cris_pipe_nonempty
;
3335 cb
->pipe_empty
= cris_pipe_empty
;
3336 cb
->time
= cris_time
;
3339 /* Process an address exception. */
3342 cris_core_signal (SIM_DESC sd
, SIM_CPU
*current_cpu
, sim_cia cia
,
3343 unsigned int map
, int nr_bytes
, address_word addr
,
3344 transfer_type transfer
, sim_core_signals sig
)
3346 sim_core_signal (sd
, current_cpu
, cia
, map
, nr_bytes
, addr
,