1 /* CRIS exception, interrupt, and trap (EIT) support
2 Copyright (C) 2004-2024 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. */
39 #ifdef HAVE_SYS_PARAM_H
40 #include <sys/param.h>
43 /* For PATH_MAX, originally. */
48 /* From ld/sysdep.h. */
50 # define SIM_PATHMAX PATH_MAX
53 # define SIM_PATHMAX MAXPATHLEN
55 # define SIM_PATHMAX 1024
59 /* The verbatim values are from asm-cris/unistd.h. */
61 #define TARGET_SYS_exit 1
62 #define TARGET_SYS_read 3
63 #define TARGET_SYS_write 4
64 #define TARGET_SYS_open 5
65 #define TARGET_SYS_close 6
66 #define TARGET_SYS_unlink 10
67 #define TARGET_SYS_time 13
68 #define TARGET_SYS_lseek 19
69 #define TARGET_SYS_getpid 20
70 #define TARGET_SYS_access 33
71 #define TARGET_SYS_kill 37
72 #define TARGET_SYS_rename 38
73 #define TARGET_SYS_pipe 42
74 #define TARGET_SYS_brk 45
75 #define TARGET_SYS_ioctl 54
76 #define TARGET_SYS_fcntl 55
77 #define TARGET_SYS_getppid 64
78 #define TARGET_SYS_setrlimit 75
79 #define TARGET_SYS_gettimeofday 78
80 #define TARGET_SYS_readlink 85
81 #define TARGET_SYS_munmap 91
82 #define TARGET_SYS_truncate 92
83 #define TARGET_SYS_ftruncate 93
84 #define TARGET_SYS_socketcall 102
85 #define TARGET_SYS_stat 106
86 #define TARGET_SYS_fstat 108
87 #define TARGET_SYS_wait4 114
88 #define TARGET_SYS_sigreturn 119
89 #define TARGET_SYS_clone 120
90 #define TARGET_SYS_uname 122
91 #define TARGET_SYS_mprotect 125
92 #define TARGET_SYS_llseek 140
93 #define TARGET_SYS_writev 146
94 #define TARGET_SYS__sysctl 149
95 #define TARGET_SYS_sched_setparam 154
96 #define TARGET_SYS_sched_getparam 155
97 #define TARGET_SYS_sched_setscheduler 156
98 #define TARGET_SYS_sched_getscheduler 157
99 #define TARGET_SYS_sched_yield 158
100 #define TARGET_SYS_sched_get_priority_max 159
101 #define TARGET_SYS_sched_get_priority_min 160
102 #define TARGET_SYS_mremap 163
103 #define TARGET_SYS_poll 168
104 #define TARGET_SYS_rt_sigaction 174
105 #define TARGET_SYS_rt_sigprocmask 175
106 #define TARGET_SYS_rt_sigsuspend 179
107 #define TARGET_SYS_getcwd 183
108 #define TARGET_SYS_ugetrlimit 191
109 #define TARGET_SYS_mmap2 192
110 #define TARGET_SYS_stat64 195
111 #define TARGET_SYS_lstat64 196
112 #define TARGET_SYS_fstat64 197
113 #define TARGET_SYS_geteuid32 201
114 #define TARGET_SYS_getuid32 199
115 #define TARGET_SYS_getegid32 202
116 #define TARGET_SYS_getgid32 200
117 #define TARGET_SYS_fcntl64 221
118 #define TARGET_SYS_set_thread_area 243
119 #define TARGET_SYS_exit_group 252
121 #define TARGET_PROT_READ 0x1
122 #define TARGET_PROT_WRITE 0x2
123 #define TARGET_PROT_EXEC 0x4
124 #define TARGET_PROT_NONE 0x0
126 #define TARGET_MAP_SHARED 0x01
127 #define TARGET_MAP_PRIVATE 0x02
128 #define TARGET_MAP_TYPE 0x0f
129 #define TARGET_MAP_FIXED 0x10
130 #define TARGET_MAP_ANONYMOUS 0x20
131 #define TARGET_MAP_DENYWRITE 0x800
133 #define TARGET_CTL_KERN 1
134 #define TARGET_CTL_VM 2
135 #define TARGET_CTL_NET 3
136 #define TARGET_CTL_PROC 4
137 #define TARGET_CTL_FS 5
138 #define TARGET_CTL_DEBUG 6
139 #define TARGET_CTL_DEV 7
140 #define TARGET_CTL_BUS 8
141 #define TARGET_CTL_ABI 9
143 #define TARGET_CTL_KERN_VERSION 4
146 #define TARGET_MREMAP_MAYMOVE 1
147 #define TARGET_MREMAP_FIXED 2
149 #define TARGET_TCGETS 0x5401
151 #define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
153 /* Seconds since 1970-01-01 to the above date + 10 minutes;
154 'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'. */
155 #define TARGET_EPOCH 1230764410
157 /* Milliseconds since start of run. We use the number of syscalls to
158 avoid introducing noise in the execution time. */
159 #define TARGET_TIME_MS(cpu) (CRIS_SIM_CPU (cpu)->syscalls)
161 /* Seconds as in time(2). */
162 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
164 #define TARGET_SCHED_OTHER 0
166 #define TARGET_RLIMIT_STACK 3
167 #define TARGET_RLIMIT_NOFILE 7
169 #define SIM_TARGET_MAX_THREADS 64
170 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
172 /* From linux/sched.h. */
173 #define TARGET_CSIGNAL 0x000000ff
174 #define TARGET_CLONE_VM 0x00000100
175 #define TARGET_CLONE_FS 0x00000200
176 #define TARGET_CLONE_FILES 0x00000400
177 #define TARGET_CLONE_SIGHAND 0x00000800
178 #define TARGET_CLONE_PID 0x00001000
179 #define TARGET_CLONE_PTRACE 0x00002000
180 #define TARGET_CLONE_VFORK 0x00004000
181 #define TARGET_CLONE_PARENT 0x00008000
182 #define TARGET_CLONE_THREAD 0x00010000
183 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
185 /* From asm-cris/poll.h. */
186 #define TARGET_POLLIN 1
188 /* From asm-cris/signal.h. */
189 #define TARGET_SIG_BLOCK 0
190 #define TARGET_SIG_UNBLOCK 1
191 #define TARGET_SIG_SETMASK 2
193 #define TARGET_SIG_DFL 0
194 #define TARGET_SIG_IGN 1
195 #define TARGET_SIG_ERR ((USI)-1)
197 #define TARGET_SIGHUP 1
198 #define TARGET_SIGINT 2
199 #define TARGET_SIGQUIT 3
200 #define TARGET_SIGILL 4
201 #define TARGET_SIGTRAP 5
202 #define TARGET_SIGABRT 6
203 #define TARGET_SIGIOT 6
204 #define TARGET_SIGBUS 7
205 #define TARGET_SIGFPE 8
206 #define TARGET_SIGKILL 9
207 #define TARGET_SIGUSR1 10
208 #define TARGET_SIGSEGV 11
209 #define TARGET_SIGUSR2 12
210 #define TARGET_SIGPIPE 13
211 #define TARGET_SIGALRM 14
212 #define TARGET_SIGTERM 15
213 #define TARGET_SIGSTKFLT 16
214 #define TARGET_SIGCHLD 17
215 #define TARGET_SIGCONT 18
216 #define TARGET_SIGSTOP 19
217 #define TARGET_SIGTSTP 20
218 #define TARGET_SIGTTIN 21
219 #define TARGET_SIGTTOU 22
220 #define TARGET_SIGURG 23
221 #define TARGET_SIGXCPU 24
222 #define TARGET_SIGXFSZ 25
223 #define TARGET_SIGVTALRM 26
224 #define TARGET_SIGPROF 27
225 #define TARGET_SIGWINCH 28
226 #define TARGET_SIGIO 29
227 #define TARGET_SIGPOLL SIGIO
228 /* Actually commented out in the kernel header. */
229 #define TARGET_SIGLOST 29
230 #define TARGET_SIGPWR 30
231 #define TARGET_SIGSYS 31
233 /* From include/asm-cris/signal.h. */
234 #define TARGET_SA_NOCLDSTOP 0x00000001
235 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
236 #define TARGET_SA_SIGINFO 0x00000004
237 #define TARGET_SA_ONSTACK 0x08000000
238 #define TARGET_SA_RESTART 0x10000000
239 #define TARGET_SA_NODEFER 0x40000000
240 #define TARGET_SA_RESETHAND 0x80000000
241 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
242 #define TARGET_SA_RESTORER 0x04000000
244 /* From linux/wait.h. */
245 #define TARGET_WNOHANG 1
246 #define TARGET_WUNTRACED 2
247 #define TARGET___WNOTHREAD 0x20000000
248 #define TARGET___WALL 0x40000000
249 #define TARGET___WCLONE 0x80000000
251 /* From linux/limits.h. */
252 #define TARGET_PIPE_BUF 4096
255 #define TARGET_R_OK 4
256 #define TARGET_W_OK 2
257 #define TARGET_X_OK 1
258 #define TARGET_F_OK 0
260 static const char stat_map
[] =
261 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
262 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
263 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
266 static const CB_TARGET_DEFS_MAP syscall_map
[] =
268 { "open", CB_SYS_open
, TARGET_SYS_open
},
269 { "close", CB_SYS_close
, TARGET_SYS_close
},
270 { "read", CB_SYS_read
, TARGET_SYS_read
},
271 { "write", CB_SYS_write
, TARGET_SYS_write
},
272 { "lseek", CB_SYS_lseek
, TARGET_SYS_lseek
},
273 { "unlink", CB_SYS_unlink
, TARGET_SYS_unlink
},
274 { "getpid", CB_SYS_getpid
, TARGET_SYS_getpid
},
275 { "fstat", CB_SYS_fstat
, TARGET_SYS_fstat64
},
276 { "lstat", CB_SYS_lstat
, TARGET_SYS_lstat64
},
277 { "stat", CB_SYS_stat
, TARGET_SYS_stat64
},
278 { "pipe", CB_SYS_pipe
, TARGET_SYS_pipe
},
279 { "rename", CB_SYS_rename
, TARGET_SYS_rename
},
280 { "truncate", CB_SYS_truncate
, TARGET_SYS_truncate
},
281 { "ftruncate", CB_SYS_ftruncate
, TARGET_SYS_ftruncate
},
285 /* An older, 32-bit-only stat mapping. */
286 static const char stat32_map
[] =
287 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
288 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
289 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
291 /* Map for calls using the 32-bit struct stat. Primarily used by the
292 newlib Linux mapping. */
293 static const CB_TARGET_DEFS_MAP syscall_stat32_map
[] =
295 { "fstat", CB_SYS_fstat
, TARGET_SYS_fstat
},
296 { "stat", CB_SYS_stat
, TARGET_SYS_stat
},
300 /* Giving the true value for the running sim process will lead to
301 non-time-invariant behavior. */
302 #define TARGET_PID 42
304 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
305 we did, we'd still don't get a register number with the "16" offset. */
306 #define TARGET_SRP_REGNUM (16+11)
308 /* Extracted by applying
309 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
310 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
311 adjusting the synonyms. */
313 static const CB_TARGET_DEFS_MAP errno_map
[] =
316 { "EPERM", EPERM
, 1 },
319 { "ENOENT", ENOENT
, 2 },
322 { "ESRCH", ESRCH
, 3 },
325 { "EINTR", EINTR
, 4 },
331 { "ENXIO", ENXIO
, 6 },
334 { "E2BIG", E2BIG
, 7 },
337 { "ENOEXEC", ENOEXEC
, 8 },
340 { "EBADF", EBADF
, 9 },
343 { "ECHILD", ECHILD
, 10 },
346 { "EAGAIN", EAGAIN
, 11 },
349 { "ENOMEM", ENOMEM
, 12 },
352 { "EACCES", EACCES
, 13 },
355 { "EFAULT", EFAULT
, 14 },
358 { "ENOTBLK", ENOTBLK
, 15 },
361 { "EBUSY", EBUSY
, 16 },
364 { "EEXIST", EEXIST
, 17 },
367 { "EXDEV", EXDEV
, 18 },
370 { "ENODEV", ENODEV
, 19 },
373 { "ENOTDIR", ENOTDIR
, 20 },
376 { "EISDIR", EISDIR
, 21 },
379 { "EINVAL", EINVAL
, 22 },
382 { "ENFILE", ENFILE
, 23 },
385 { "EMFILE", EMFILE
, 24 },
388 { "ENOTTY", ENOTTY
, 25 },
391 { "ETXTBSY", ETXTBSY
, 26 },
394 { "EFBIG", EFBIG
, 27 },
397 { "ENOSPC", ENOSPC
, 28 },
400 { "ESPIPE", ESPIPE
, 29 },
403 { "EROFS", EROFS
, 30 },
406 { "EMLINK", EMLINK
, 31 },
409 { "EPIPE", EPIPE
, 32 },
412 { "EDOM", EDOM
, 33 },
415 { "ERANGE", ERANGE
, 34 },
418 { "EDEADLK", EDEADLK
, 35 },
421 { "ENAMETOOLONG", ENAMETOOLONG
, 36 },
424 { "ENOLCK", ENOLCK
, 37 },
427 { "ENOSYS", ENOSYS
, 38 },
430 { "ENOTEMPTY", ENOTEMPTY
, 39 },
433 { "ELOOP", ELOOP
, 40 },
436 { "EWOULDBLOCK", EWOULDBLOCK
, 11 },
439 { "ENOMSG", ENOMSG
, 42 },
442 { "EIDRM", EIDRM
, 43 },
445 { "ECHRNG", ECHRNG
, 44 },
448 { "EL2NSYNC", EL2NSYNC
, 45 },
451 { "EL3HLT", EL3HLT
, 46 },
454 { "EL3RST", EL3RST
, 47 },
457 { "ELNRNG", ELNRNG
, 48 },
460 { "EUNATCH", EUNATCH
, 49 },
463 { "ENOCSI", ENOCSI
, 50 },
466 { "EL2HLT", EL2HLT
, 51 },
469 { "EBADE", EBADE
, 52 },
472 { "EBADR", EBADR
, 53 },
475 { "EXFULL", EXFULL
, 54 },
478 { "ENOANO", ENOANO
, 55 },
481 { "EBADRQC", EBADRQC
, 56 },
484 { "EBADSLT", EBADSLT
, 57 },
487 { "EDEADLOCK", EDEADLOCK
, 35 },
490 { "EBFONT", EBFONT
, 59 },
493 { "ENOSTR", ENOSTR
, 60 },
496 { "ENODATA", ENODATA
, 61 },
499 { "ETIME", ETIME
, 62 },
502 { "ENOSR", ENOSR
, 63 },
505 { "ENONET", ENONET
, 64 },
508 { "ENOPKG", ENOPKG
, 65 },
511 { "EREMOTE", EREMOTE
, 66 },
514 { "ENOLINK", ENOLINK
, 67 },
517 { "EADV", EADV
, 68 },
520 { "ESRMNT", ESRMNT
, 69 },
523 { "ECOMM", ECOMM
, 70 },
526 { "EPROTO", EPROTO
, 71 },
529 { "EMULTIHOP", EMULTIHOP
, 72 },
532 { "EDOTDOT", EDOTDOT
, 73 },
535 { "EBADMSG", EBADMSG
, 74 },
538 { "EOVERFLOW", EOVERFLOW
, 75 },
541 { "ENOTUNIQ", ENOTUNIQ
, 76 },
544 { "EBADFD", EBADFD
, 77 },
547 { "EREMCHG", EREMCHG
, 78 },
550 { "ELIBACC", ELIBACC
, 79 },
553 { "ELIBBAD", ELIBBAD
, 80 },
556 { "ELIBSCN", ELIBSCN
, 81 },
559 { "ELIBMAX", ELIBMAX
, 82 },
562 { "ELIBEXEC", ELIBEXEC
, 83 },
565 { "EILSEQ", EILSEQ
, 84 },
568 { "ERESTART", ERESTART
, 85 },
571 { "ESTRPIPE", ESTRPIPE
, 86 },
574 { "EUSERS", EUSERS
, 87 },
577 { "ENOTSOCK", ENOTSOCK
, 88 },
580 { "EDESTADDRREQ", EDESTADDRREQ
, 89 },
583 { "EMSGSIZE", EMSGSIZE
, 90 },
586 { "EPROTOTYPE", EPROTOTYPE
, 91 },
589 { "ENOPROTOOPT", ENOPROTOOPT
, 92 },
591 #ifdef EPROTONOSUPPORT
592 { "EPROTONOSUPPORT", EPROTONOSUPPORT
, 93 },
594 #ifdef ESOCKTNOSUPPORT
595 { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT
, 94 },
598 { "EOPNOTSUPP", EOPNOTSUPP
, 95 },
601 { "EPFNOSUPPORT", EPFNOSUPPORT
, 96 },
604 { "EAFNOSUPPORT", EAFNOSUPPORT
, 97 },
607 { "EADDRINUSE", EADDRINUSE
, 98 },
610 { "EADDRNOTAVAIL", EADDRNOTAVAIL
, 99 },
613 { "ENETDOWN", ENETDOWN
, 100 },
616 { "ENETUNREACH", ENETUNREACH
, 101 },
619 { "ENETRESET", ENETRESET
, 102 },
622 { "ECONNABORTED", ECONNABORTED
, 103 },
625 { "ECONNRESET", ECONNRESET
, 104 },
628 { "ENOBUFS", ENOBUFS
, 105 },
631 { "EISCONN", EISCONN
, 106 },
634 { "ENOTCONN", ENOTCONN
, 107 },
637 { "ESHUTDOWN", ESHUTDOWN
, 108 },
640 { "ETOOMANYREFS", ETOOMANYREFS
, 109 },
643 { "ETIMEDOUT", ETIMEDOUT
, 110 },
646 { "ECONNREFUSED", ECONNREFUSED
, 111 },
649 { "EHOSTDOWN", EHOSTDOWN
, 112 },
652 { "EHOSTUNREACH", EHOSTUNREACH
, 113 },
655 { "EALREADY", EALREADY
, 114 },
658 { "EINPROGRESS", EINPROGRESS
, 115 },
661 { "ESTALE", ESTALE
, 116 },
664 { "EUCLEAN", EUCLEAN
, 117 },
667 { "ENOTNAM", ENOTNAM
, 118 },
670 { "ENAVAIL", ENAVAIL
, 119 },
673 { "EISNAM", EISNAM
, 120 },
676 { "EREMOTEIO", EREMOTEIO
, 121 },
679 { "EDQUOT", EDQUOT
, 122 },
682 { "ENOMEDIUM", ENOMEDIUM
, 123 },
685 { "EMEDIUMTYPE", EMEDIUMTYPE
, 124 },
690 /* Extracted by applying
691 perl -ne 'if ($_ =~ /^#define/) { split;
692 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
693 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
694 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
695 installation and removing synonyms and unnecessary items. Don't
696 forget the end-marker. */
698 /* These we treat specially, as they're used in the fcntl F_GETFL
699 syscall. For consistency, open_map is also manually edited to use
701 #define TARGET_O_ACCMODE 0x3
702 #define TARGET_O_RDONLY 0x0
703 #define TARGET_O_WRONLY 0x1
705 static const CB_TARGET_DEFS_MAP open_map
[] = {
707 { "O_ACCMODE", O_ACCMODE
, TARGET_O_ACCMODE
},
710 { "O_RDONLY", O_RDONLY
, TARGET_O_RDONLY
},
713 { "O_WRONLY", O_WRONLY
, TARGET_O_WRONLY
},
716 { "O_RDWR", O_RDWR
, 0x2 },
719 { "O_CREAT", O_CREAT
, 0x40 },
722 { "O_EXCL", O_EXCL
, 0x80 },
725 { "O_NOCTTY", O_NOCTTY
, 0x100 },
728 { "O_TRUNC", O_TRUNC
, 0x200 },
731 { "O_APPEND", O_APPEND
, 0x400 },
734 { "O_NONBLOCK", O_NONBLOCK
, 0x800 },
737 { "O_NDELAY", O_NDELAY
, 0x0 },
740 { "O_SYNC", O_SYNC
, 0x1000 },
743 { "FASYNC", FASYNC
, 0x2000 },
746 { "O_DIRECT", O_DIRECT
, 0x4000 },
749 { "O_LARGEFILE", O_LARGEFILE
, 0x8000 },
752 { "O_DIRECTORY", O_DIRECTORY
, 0x10000 },
755 { "O_NOFOLLOW", O_NOFOLLOW
, 0x20000 },
760 /* Let's be less drastic and more traceable. FIXME: mark as noreturn. */
762 sim_io_error (sd, "simulator unhandled condition at %s:%d", \
763 __FUNCTION__, __LINE__)
765 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
766 static SIM_CPU
*current_cpu_for_cb_callback
;
768 static USI
create_map (SIM_DESC
, struct cris_sim_mmapped_page
**,
770 static USI
unmap_pages (SIM_DESC
, struct cris_sim_mmapped_page
**,
772 static USI
is_mapped (SIM_DESC
, struct cris_sim_mmapped_page
**,
774 static void dump_statistics (SIM_CPU
*current_cpu
);
775 static void make_first_thread (SIM_CPU
*current_cpu
);
777 /* When we risk running self-modified code (as in trampolines), this is
778 called from special-case insns. The silicon CRIS CPU:s have enough
779 cache snooping implemented making this a simulator-only issue. Tests:
780 gcc.c-torture/execute/931002-1.c execution, -O3 -g
781 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
784 cris_flush_simulator_decode_cache (SIM_CPU
*current_cpu
,
785 USI pc ATTRIBUTE_UNUSED
)
787 SIM_DESC sd
= CPU_STATE (current_cpu
);
790 if (USING_SCACHE_P (sd
))
791 scache_flush_cpu (current_cpu
);
795 /* Output statistics at the end of a run. */
797 dump_statistics (SIM_CPU
*current_cpu
)
799 SIM_DESC sd
= CPU_STATE (current_cpu
);
800 CRIS_MISC_PROFILE
*profp
801 = CPU_CRIS_MISC_PROFILE (current_cpu
);
802 uint64_t total
= profp
->basic_cycle_count
;
804 /* Historically, these messages have gone to stderr, so we'll keep it
805 that way. It's also easier to then tell it from normal program
806 output. FIXME: Add redirect option like "run -e file". */
808 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
809 what's included in the "total" count only. */
810 switch (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
811 & FLAG_CRIS_MISC_PROFILE_ALL
)
813 case FLAG_CRIS_MISC_PROFILE_SIMPLE
:
814 sim_io_eprintf (sd
, "Basic clock cycles, total @: %" PRIu64
"\n", total
);
817 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
818 total
+= profp
->unaligned_mem_dword_count
;
820 "Clock cycles including stall cycles for unaligned "
821 "accesses @: %" PRIu64
"\n",
825 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
827 += (profp
->memsrc_stall_count
828 + profp
->memraw_stall_count
829 + profp
->movemsrc_stall_count
830 + profp
->movemdst_stall_count
831 + profp
->mulsrc_stall_count
832 + profp
->jumpsrc_stall_count
833 + profp
->unaligned_mem_dword_count
);
834 sim_io_eprintf (sd
, "Schedulable clock cycles, total @: %" PRIu64
"\n",
838 case FLAG_CRIS_MISC_PROFILE_ALL
:
840 += (profp
->memsrc_stall_count
841 + profp
->memraw_stall_count
842 + profp
->movemsrc_stall_count
843 + profp
->movemdst_stall_count
844 + profp
->movemaddr_stall_count
845 + profp
->mulsrc_stall_count
846 + profp
->jumpsrc_stall_count
847 + profp
->branch_stall_count
848 + profp
->jumptarget_stall_count
849 + profp
->unaligned_mem_dword_count
);
850 sim_io_eprintf (sd
, "All accounted clock cycles, total @: %" PRIu64
"\n",
855 sim_engine_abort (sd
, current_cpu
, 0,
856 "Internal inconsistency at %s:%d",
860 /* For v32, unaligned_mem_dword_count should always be 0. For
861 v10, memsrc_stall_count should always be 0. */
862 sim_io_eprintf (sd
, "Memory source stall cycles: %" PRIu64
"\n",
863 profp
->memsrc_stall_count
+ profp
->unaligned_mem_dword_count
);
864 sim_io_eprintf (sd
, "Memory read-after-write stall cycles: %" PRIu64
"\n",
865 profp
->memraw_stall_count
);
866 sim_io_eprintf (sd
, "Movem source stall cycles: %" PRIu64
"\n",
867 profp
->movemsrc_stall_count
);
868 sim_io_eprintf (sd
, "Movem destination stall cycles: %" PRIu64
"\n",
869 profp
->movemdst_stall_count
);
870 sim_io_eprintf (sd
, "Movem address stall cycles: %" PRIu64
"\n",
871 profp
->movemaddr_stall_count
);
872 sim_io_eprintf (sd
, "Multiplication source stall cycles: %" PRIu64
"\n",
873 profp
->mulsrc_stall_count
);
874 sim_io_eprintf (sd
, "Jump source stall cycles: %" PRIu64
"\n",
875 profp
->jumpsrc_stall_count
);
876 sim_io_eprintf (sd
, "Branch misprediction stall cycles: %" PRIu64
"\n",
877 profp
->branch_stall_count
);
878 sim_io_eprintf (sd
, "Jump target stall cycles: %" PRIu64
"\n",
879 profp
->jumptarget_stall_count
);
882 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
883 Return 1 if a overlap detected, 0 otherwise. */
886 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED
,
887 struct cris_sim_mmapped_page
**rootp
,
890 struct cris_sim_mmapped_page
*mapp
;
892 if (len
== 0 || (len
& 8191))
895 /* Iterate over the reverse-address sorted pages until we find a page in
896 or lower than the checked area. */
897 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
898 if (mapp
->addr
< addr
+ len
&& mapp
->addr
>= addr
)
904 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
905 Return 1 if the whole area is mapped, 0 otherwise. */
908 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED
,
909 struct cris_sim_mmapped_page
**rootp
,
912 struct cris_sim_mmapped_page
*mapp
;
914 if (len
== 0 || (len
& 8191))
917 /* Iterate over the reverse-address sorted pages until we find a page
918 lower than the checked area. */
919 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
920 if (addr
== mapp
->addr
&& len
== 8192)
922 else if (addr
+ len
> mapp
->addr
)
928 /* Provide a prototype to silence -Wmissing-prototypes. */
929 void cris_dump_map (SIM_CPU
*current_cpu
);
931 /* Debug helper; to be run from gdb. */
933 cris_dump_map (SIM_CPU
*current_cpu
)
935 struct cris_sim_cpu
*cris_cpu
= CRIS_SIM_CPU (current_cpu
);
936 struct cris_sim_mmapped_page
*mapp
;
939 for (mapp
= cris_cpu
->highest_mmapped_page
,
940 start
= mapp
== NULL
? 0 : mapp
->addr
+ 8192,
941 end
= mapp
== NULL
? 0 : mapp
->addr
+ 8191;
945 if (mapp
->addr
!= start
- 8192)
947 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
948 end
= mapp
->addr
+ 8191;
954 if (cris_cpu
->highest_mmapped_page
!= NULL
)
955 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
958 /* Create mmapped memory. ADDR is -1 if any address will do. Caller
959 must make sure that the address isn't already mapped. */
962 create_map (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
965 struct cris_sim_mmapped_page
*mapp
;
966 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
967 USI new_addr
= 0x40000000;
969 if (addr
!= (USI
) -1)
971 else if (*rootp
&& rootp
[0]->addr
>= new_addr
)
972 new_addr
= rootp
[0]->addr
+ 8192;
979 /* Which is better: return an error for this, or just round it up? */
982 /* Do a recursive call for each page in the request. */
983 for (page_addr
= new_addr
; len
!= 0; page_addr
+= 8192, len
-= 8192)
984 if (create_map (sd
, rootp
, page_addr
, 8192) >= (USI
) -8191)
991 mapp
!= NULL
&& mapp
->addr
> new_addr
;
993 higher_prevp
= &mapp
->prev
;
995 /* Assert for consistency that we don't create duplicate maps. */
996 if (is_mapped (sd
, rootp
, new_addr
, len
))
999 /* Allocate the new page, on the next higher page from the last one
1000 allocated, and link in the new descriptor before previous ones. */
1001 mapp
= malloc (sizeof (*mapp
));
1004 return (USI
) -ENOMEM
;
1006 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1010 mapp
->addr
= new_addr
;
1011 mapp
->prev
= *higher_prevp
;
1012 *higher_prevp
= mapp
;
1017 /* Unmap one or more pages. */
1020 unmap_pages (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
1023 struct cris_sim_mmapped_page
*mapp
;
1024 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
1032 /* Which is better: return an error for this, or just round it up? */
1035 /* Loop backwards to make each call is O(1) over the number of pages
1036 allocated, if we're unmapping from the high end of the pages. */
1037 for (page_addr
= addr
+ len
- 8192;
1040 if (unmap_pages (sd
, rootp
, page_addr
, 8192))
1043 if (unmap_pages (sd
, rootp
, addr
, 8192))
1049 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
> addr
; mapp
= mapp
->prev
)
1050 higher_prevp
= &mapp
->prev
;
1052 if (mapp
== NULL
|| mapp
->addr
!= addr
)
1055 *higher_prevp
= mapp
->prev
;
1056 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1061 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1064 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC vpc
)
1066 SIM_DESC sd
= CPU_STATE (current_cpu
);
1068 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
1072 /* Swap one context for another. */
1075 schedule (SIM_CPU
*current_cpu
, int next
)
1077 struct cris_sim_cpu
*cris_cpu
= CRIS_SIM_CPU (current_cpu
);
1079 /* Need to mark context-switches in the trace output. */
1080 if ((CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1081 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE
))
1082 cris_trace_printf (CPU_STATE (current_cpu
), current_cpu
,
1085 /* Copy the current context (if there is one) to its slot. */
1086 if (cris_cpu
->thread_data
[cris_cpu
->threadno
].cpu_context
)
1087 memcpy (cris_cpu
->thread_data
[cris_cpu
->threadno
].cpu_context
,
1088 &cris_cpu
->cpu_data_placeholder
,
1089 cris_cpu
->thread_cpu_data_size
);
1091 /* Copy the new context from its slot. */
1092 memcpy (&cris_cpu
->cpu_data_placeholder
,
1093 cris_cpu
->thread_data
[next
].cpu_context
,
1094 cris_cpu
->thread_cpu_data_size
);
1096 /* Update needed stuff to indicate the new context. */
1097 cris_cpu
->threadno
= next
;
1099 /* Handle pending signals. */
1100 if (cris_cpu
->thread_data
[next
].sigpending
1101 /* We don't run nested signal handlers. This means that pause(2)
1102 and sigsuspend(2) do not work in sighandlers, but that
1103 shouldn't be too hard a restriction. It also greatly
1104 simplifies the code. */
1105 && cris_cpu
->thread_data
[next
].cpu_context_atsignal
== NULL
)
1109 /* See if there's really a pending, non-blocked handler. We don't
1110 queue signals, so just use the first one in ascending order. */
1111 for (sig
= 0; sig
< 64; sig
++)
1112 if (cris_cpu
->thread_data
[next
].sigdata
[sig
].pending
1113 && !cris_cpu
->thread_data
[next
].sigdata
[sig
].blocked
)
1119 USI pc
= sim_pc_get (current_cpu
);
1121 /* It's simpler to save the CPU context inside the simulator
1122 than on the stack. */
1123 cris_cpu
->thread_data
[next
].cpu_context_atsignal
1124 = (*cris_cpu
->make_thread_cpu_data
) (current_cpu
,
1125 cris_cpu
->thread_data
[next
]
1128 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1129 sp
= bfd_getl32 (regbuf
);
1131 /* Make sure we have an aligned stack. */
1134 /* Make room for the signal frame, aligned. FIXME: Check that
1135 the memory exists, map it in if absent. (BTW, should also
1136 implement on-access automatic stack allocation). */
1139 /* This isn't the same signal frame as the kernel uses, because
1140 we don't want to bother getting all registers on and off the
1143 /* First, we store the currently blocked signals. */
1145 for (i
= 0; i
< 32; i
++)
1147 |= cris_cpu
->thread_data
[next
].sigdata
[i
+ 1].blocked
<< i
;
1148 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
, blocked
);
1150 for (i
= 0; i
< 31; i
++)
1152 |= cris_cpu
->thread_data
[next
].sigdata
[i
+ 33].blocked
<< i
;
1153 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
+ 4, blocked
);
1155 /* Then, the actual instructions. This is CPU-specific, but we
1156 use instructions from the common subset for v10 and v32 which
1157 should be safe for the time being but could be parametrized
1159 /* MOVU.W [PC+],R9. */
1160 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 8, 0x9c5f);
1161 /* .WORD TARGET_SYS_sigreturn. */
1162 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 10,
1163 TARGET_SYS_sigreturn
);
1165 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 12, 0xe93d);
1167 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1168 instruction. Still, it doesn't matter because v10 has no
1169 delay slot for BREAK so it will not be executed). */
1170 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 16, 0x05b0);
1172 /* Modify registers to hold the right values for the sighandler
1173 context: updated stackpointer and return address pointing to
1174 the sigreturn stub. */
1175 bfd_putl32 (sp
, regbuf
);
1176 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1177 bfd_putl32 (sp
+ 8, regbuf
);
1178 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, TARGET_SRP_REGNUM
,
1181 cris_cpu
->thread_data
[next
].sigdata
[sig
].pending
= 0;
1183 /* Block this signal (for the duration of the sighandler). */
1184 cris_cpu
->thread_data
[next
].sigdata
[sig
].blocked
= 1;
1186 sim_pc_set (current_cpu
, cris_cpu
->sighandler
[sig
]);
1187 bfd_putl32 (sig
, regbuf
);
1188 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
,
1191 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1192 needed all this for, specifies a SA_SIGINFO call but treats it
1193 like an ordinary sighandler; only the signal number argument is
1194 inspected. To make future need to implement SA_SIGINFO
1195 correctly possible, we set the siginfo argument register to a
1196 magic (hopefully non-address) number. (NB: then, you should
1197 just need to pass the siginfo argument; it seems you probably
1198 don't need to implement the specific rt_sigreturn.) */
1199 bfd_putl32 (0xbad5161f, regbuf
);
1200 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R11
,
1203 /* The third argument is unused and the kernel sets it to 0. */
1204 bfd_putl32 (0, regbuf
);
1205 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R12
,
1210 /* No, there actually was no pending signal for this thread. Reset
1212 cris_cpu
->thread_data
[next
].sigpending
= 0;
1216 /* Reschedule the simplest possible way until something else is absolutely
1218 - A. Find the next process (round-robin) that doesn't have at_syscall
1220 - B. If there is none, just run the next process, round-robin.
1221 - Clear at_syscall for the current process. */
1224 reschedule (SIM_CPU
*current_cpu
)
1226 SIM_DESC sd
= CPU_STATE (current_cpu
);
1227 struct cris_sim_cpu
*cris_cpu
= CRIS_SIM_CPU (current_cpu
);
1230 /* Iterate over all thread slots, because after a few thread creations
1231 and exits, we don't know where the live ones are. */
1232 for (i
= (cris_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1233 i
!= cris_cpu
->threadno
;
1234 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1235 if (cris_cpu
->thread_data
[i
].cpu_context
1236 && cris_cpu
->thread_data
[i
].at_syscall
== 0)
1238 schedule (current_cpu
, i
);
1242 /* Pick any next live thread. */
1243 for (i
= (cris_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1244 i
!= cris_cpu
->threadno
;
1245 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1246 if (cris_cpu
->thread_data
[i
].cpu_context
)
1248 schedule (current_cpu
, i
);
1252 /* More than one live thread, but we couldn't find the next one? */
1256 /* Set up everything to receive (or IGN) an incoming signal to the
1260 deliver_signal (SIM_CPU
*current_cpu
, int sig
, unsigned int pid
)
1262 struct cris_sim_cpu
*cris_cpu
= CRIS_SIM_CPU (current_cpu
);
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 cris_cpu->thread_data[i].cpu_context != NULL would be wrong). */
1270 if (cris_cpu
->thread_data
[i
].threadid
== pid
- TARGET_PID
)
1273 switch (cris_cpu
->sighandler
[sig
])
1275 case TARGET_SIG_DFL
:
1278 /* The following according to the glibc
1279 documentation. (The kernel code has non-obvious
1280 execution paths.) */
1283 case TARGET_SIGSEGV
:
1285 case TARGET_SIGABRT
:
1286 case TARGET_SIGTRAP
:
1289 case TARGET_SIGTERM
:
1291 case TARGET_SIGQUIT
:
1292 case TARGET_SIGKILL
:
1295 case TARGET_SIGALRM
:
1296 case TARGET_SIGVTALRM
:
1297 case TARGET_SIGPROF
:
1298 case TARGET_SIGSTOP
:
1300 case TARGET_SIGPIPE
:
1301 case TARGET_SIGLOST
:
1302 case TARGET_SIGXCPU
:
1303 case TARGET_SIGXFSZ
:
1304 case TARGET_SIGUSR1
:
1305 case TARGET_SIGUSR2
:
1306 sim_io_eprintf (CPU_STATE (current_cpu
),
1307 "Exiting pid %d due to signal %d\n",
1309 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1310 NULL
, pc
, sim_stopped
,
1311 sig
== TARGET_SIGABRT
1312 ? SIM_SIGABRT
: SIM_SIGILL
);
1315 /* The default for all other signals is to be ignored. */
1320 case TARGET_SIG_IGN
:
1323 case TARGET_SIGKILL
:
1324 case TARGET_SIGSTOP
:
1325 /* Can't ignore these signals. */
1326 sim_io_eprintf (CPU_STATE (current_cpu
),
1327 "Exiting pid %d due to signal %d\n",
1329 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1330 NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1339 /* Mark the signal as pending, making schedule () check
1340 closer. The signal will be handled when the thread is
1341 scheduled and the signal is unblocked. */
1342 cris_cpu
->thread_data
[i
].sigdata
[sig
].pending
= 1;
1343 cris_cpu
->thread_data
[i
].sigpending
= 1;
1348 sim_io_eprintf (CPU_STATE (current_cpu
),
1349 "Unimplemented signal: %d\n", sig
);
1350 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
1351 sim_stopped
, SIM_SIGILL
);
1356 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu
)),
1360 /* Make the vector and the first item, the main thread. */
1363 make_first_thread (SIM_CPU
*current_cpu
)
1365 SIM_DESC sd
= CPU_STATE (current_cpu
);
1366 struct cris_sim_cpu
*cris_cpu
= CRIS_SIM_CPU (current_cpu
);
1368 cris_cpu
->thread_data
1369 = xcalloc (1, SIM_TARGET_MAX_THREADS
* sizeof (cris_cpu
->thread_data
[0]));
1370 cris_cpu
->thread_data
[0].cpu_context
1371 = (*cris_cpu
->make_thread_cpu_data
) (current_cpu
,
1372 &cris_cpu
->cpu_data_placeholder
);
1373 cris_cpu
->thread_data
[0].parent_threadid
= -1;
1375 /* For good measure. */
1376 if (TARGET_SIG_DFL
!= 0)
1380 /* Handle unknown system calls. Returns (if it does) the syscall
1383 static USI
ATTRIBUTE_PRINTF (3, 4)
1384 cris_unknown_syscall (SIM_CPU
*current_cpu
, USI pc
, char *s
, ...)
1386 SIM_DESC sd
= CPU_STATE (current_cpu
);
1387 host_callback
*cb
= STATE_CALLBACK (sd
);
1389 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
1390 || cris_unknown_syscall_action
== CRIS_USYSC_MSG_ENOSYS
)
1395 sim_io_evprintf (sd
, s
, ap
);
1398 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
)
1399 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1402 return -cb_host_to_target_errno (cb
, ENOSYS
);
1405 /* Main function: the handler of the "break 13" syscall insn. */
1408 cris_break_13_handler (SIM_CPU
*current_cpu
, USI callnum
, USI arg1
,
1409 USI arg2
, USI arg3
, USI arg4
, USI arg5
, USI arg6
,
1413 SIM_DESC sd
= CPU_STATE (current_cpu
);
1414 struct cris_sim_cpu
*cris_cpu
= CRIS_SIM_CPU (current_cpu
);
1415 host_callback
*cb
= STATE_CALLBACK (sd
);
1417 int threadno
= cris_cpu
->threadno
;
1419 cris_cpu
->syscalls
++;
1421 CB_SYSCALL_INIT (&s
);
1427 /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need
1428 to sign-extend the lseek offset to be passed as a signed number,
1429 else we'll truncate it to something > 2GB on hosts where sizeof
1430 long > sizeof USI. We avoid doing it for all syscalls, as arg2 is
1431 e.g. an address for some syscalls. */
1432 if (callnum
== TARGET_SYS_lseek
)
1435 if (callnum
== TARGET_SYS_exit_group
1436 || (callnum
== TARGET_SYS_exit
&& cris_cpu
->m1threads
== 0))
1438 if (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1439 & FLAG_CRIS_MISC_PROFILE_ALL
)
1440 dump_statistics (current_cpu
);
1441 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
1446 s
.read_mem
= sim_syscall_read_mem
;
1447 s
.write_mem
= sim_syscall_write_mem
;
1449 current_cpu_for_cb_callback
= current_cpu
;
1451 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1453 sim_engine_abort (sd
, current_cpu
, pc
,
1454 "Break 13: invalid %d? Returned %ld\n", callnum
,
1458 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
1460 if (s
.errcode
!= 0 && s
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
1462 /* If the generic simulator call said ENOSYS, then let's try the
1463 ones we know ourselves.
1465 The convention is to provide *very limited* functionality on an
1466 as-needed basis, only what's covered by the test-suite, tests
1467 added when functionality changes and abort with a descriptive
1468 message for *everything* else. Where there's no test-case, we
1473 /* It's a pretty safe bet that the "old setup() system call"
1474 number will not be re-used; we can't say the same for higher
1475 numbers. We treat this simulator-generated call as "wait
1476 forever"; we re-run this insn. The wait is ended by a
1477 callback. Sanity check that this is the reason we got
1479 if (cris_cpu
->thread_data
== NULL
1480 || (cris_cpu
->thread_data
[threadno
].pipe_write_fd
== 0))
1481 goto unimplemented_syscall
;
1483 sim_pc_set (current_cpu
, pc
);
1487 case TARGET_SYS_fcntl64
:
1488 case TARGET_SYS_fcntl
:
1493 Glibc checks stdin, stdout and stderr fd:s for
1494 close-on-exec security sanity. We just need to provide a
1495 OK return value. If we really need to have a
1496 close-on-exec flag true, we could just do a real fcntl
1502 /* F_SETFD. Just ignore attempts to set the close-on-exec
1508 /* F_GETFL. Check for the special case for open+fdopen. */
1509 if (cris_cpu
->last_syscall
== TARGET_SYS_open
1510 && arg1
== cris_cpu
->last_open_fd
)
1512 retval
= cris_cpu
->last_open_flags
& TARGET_O_ACCMODE
;
1517 /* Because we can't freopen fd:s 0, 1, 2 to mean
1518 something else than stdin, stdout and stderr
1519 (sim/common/syscall.c:cb_syscall special cases fd
1520 0, 1 and 2), we know what flags that we can
1521 sanely return for these fd:s. */
1522 retval
= TARGET_O_RDONLY
;
1525 else if (arg1
== 1 || arg1
== 2)
1527 retval
= TARGET_O_WRONLY
;
1530 ATTRIBUTE_FALLTHROUGH
;
1532 /* Nothing else is implemented. */
1534 = cris_unknown_syscall (current_cpu
, pc
,
1535 "Unimplemented %s syscall "
1536 "(fd: 0x%lx: cmd: 0x%lx arg: "
1538 callnum
== TARGET_SYS_fcntl
1539 ? "fcntl" : "fcntl64",
1540 (unsigned long) (USI
) arg1
,
1541 (unsigned long) (USI
) arg2
,
1542 (unsigned long) (USI
) arg3
);
1547 case TARGET_SYS_uname
:
1549 /* Fill in a few constants to appease glibc. */
1550 static char sim_utsname
[6][65] =
1556 "cris", /* Overwritten below. */
1560 /* Having the hardware type in Linux equal to the bfd
1561 printable name is deliberate: if you make config.guess
1562 work on your Linux-type system the usual way, it
1563 probably will; either the bfd printable_name or the
1564 ambiguous arch_name. */
1565 strcpy (sim_utsname
[4], STATE_ARCHITECTURE (sd
)->printable_name
);
1567 if ((s
.write_mem
) (cb
, &s
, arg1
, (const char *) sim_utsname
,
1568 sizeof (sim_utsname
))
1569 != sizeof (sim_utsname
))
1570 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
1576 case TARGET_SYS_geteuid32
:
1577 /* We tell the truth with these. Maybe we shouldn't, but it
1578 should match the "stat" information. */
1579 retval
= geteuid ();
1582 case TARGET_SYS_getuid32
:
1586 case TARGET_SYS_getegid32
:
1587 retval
= getegid ();
1590 case TARGET_SYS_getgid32
:
1594 case TARGET_SYS_brk
:
1595 /* Most often, we just return the argument, like the Linux
1600 retval
= cris_cpu
->endbrk
;
1601 else if (arg1
<= cris_cpu
->endmem
)
1602 cris_cpu
->endbrk
= arg1
;
1605 USI new_end
= (arg1
+ 8191) & ~8191;
1607 /* If the simulator wants to brk more than a certain very
1608 large amount, something is wrong. FIXME: Return an error
1609 or abort? Have command-line selectable? */
1610 if (new_end
- cris_cpu
->endmem
> SIM_MAX_ALLOC_CHUNK
)
1612 cris_cpu
->endbrk
= cris_cpu
->endmem
;
1613 retval
= cris_cpu
->endmem
;
1617 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1619 new_end
- cris_cpu
->endmem
,
1621 cris_cpu
->endbrk
= arg1
;
1622 cris_cpu
->endmem
= new_end
;
1626 case TARGET_SYS_getpid
:
1627 /* Correct until CLONE_THREAD is implemented. */
1628 retval
= cris_cpu
->thread_data
== NULL
1630 : TARGET_PID
+ cris_cpu
->thread_data
[threadno
].threadid
;
1633 case TARGET_SYS_getppid
:
1634 /* Correct until CLONE_THREAD is implemented. */
1635 retval
= cris_cpu
->thread_data
== NULL
1638 + cris_cpu
->thread_data
[threadno
].parent_threadid
);
1641 case TARGET_SYS_mmap2
:
1650 /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1651 still masked away this bit, so let's just ignore
1653 flags
&= ~TARGET_MAP_DENYWRITE
;
1655 /* If the simulator wants to mmap more than the very large
1656 limit, something is wrong. FIXME: Return an error or
1657 abort? Have command-line selectable? */
1658 if (len
> SIM_MAX_ALLOC_CHUNK
)
1660 retval
= -cb_host_to_target_errno (cb
, ENOMEM
);
1664 if ((prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
)
1666 != (TARGET_PROT_READ
1668 | TARGET_PROT_EXEC
))
1669 && (prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
))
1670 && prot
!= TARGET_PROT_READ
)
1671 || (flags
!= (TARGET_MAP_ANONYMOUS
| TARGET_MAP_PRIVATE
)
1672 && flags
!= TARGET_MAP_PRIVATE
1673 && flags
!= (TARGET_MAP_ANONYMOUS
1674 | TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1675 && flags
!= (TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1676 && flags
!= TARGET_MAP_SHARED
)
1678 && prot
!= TARGET_PROT_READ
1679 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1680 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1681 || (fd
== (USI
) -1 && pgoff
!= 0)
1682 || (fd
!= (USI
) -1 && (flags
& TARGET_MAP_ANONYMOUS
)))
1685 = cris_unknown_syscall (current_cpu
, pc
,
1686 "Unimplemented mmap2 call "
1687 "(0x%lx, 0x%lx, 0x%lx, "
1688 "0x%lx, 0x%lx, 0x%lx)\n",
1689 (unsigned long) arg1
,
1690 (unsigned long) arg2
,
1691 (unsigned long) arg3
,
1692 (unsigned long) arg4
,
1693 (unsigned long) arg5
,
1694 (unsigned long) arg6
);
1697 else if (fd
!= (USI
) -1)
1704 /* A non-aligned argument is allowed for files. */
1705 USI newlen
= (len
+ 8191) & ~8191;
1707 /* We only support read, read|exec, and read|write,
1708 which we should already have checked. Check again
1710 if (prot
!= TARGET_PROT_READ
1711 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1712 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1715 if (flags
& TARGET_MAP_FIXED
)
1716 unmap_pages (sd
, &cris_cpu
->highest_mmapped_page
,
1718 else if (is_mapped (sd
, &cris_cpu
->highest_mmapped_page
,
1723 = create_map (sd
, &cris_cpu
->highest_mmapped_page
,
1724 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1728 if (newaddr
>= (USI
) -8191)
1731 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1735 /* We were asked for MAP_FIXED, but couldn't. */
1736 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1739 unmap_pages (sd
, &cris_cpu
->highest_mmapped_page
,
1741 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1745 /* Find the current position in the file. */
1746 s
.func
= TARGET_SYS_lseek
;
1750 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1757 /* Move to the correct offset in the file. */
1758 s
.func
= TARGET_SYS_lseek
;
1760 s
.arg2
= pgoff
*8192;
1762 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1768 /* Use the standard read callback to read in "len"
1770 s
.func
= TARGET_SYS_read
;
1774 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1777 /* If the result is a page or more lesser than what
1778 was requested, something went wrong. */
1779 if (len
>= 8192 && (USI
) s
.result
<= len
- 8192)
1782 /* After reading, we need to go back to the previous
1783 position in the file. */
1784 s
.func
= TARGET_SYS_lseek
;
1788 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1790 if (pos
!= (USI
) s
.result
)
1797 USI newlen
= (len
+ 8191) & ~8191;
1800 if (flags
& TARGET_MAP_FIXED
)
1801 unmap_pages (sd
, &cris_cpu
->highest_mmapped_page
,
1803 else if (is_mapped (sd
, &cris_cpu
->highest_mmapped_page
,
1807 newaddr
= create_map (sd
, &cris_cpu
->highest_mmapped_page
,
1808 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1812 if (newaddr
>= (USI
) -8191)
1813 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1817 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1820 unmap_pages (sd
, &cris_cpu
->highest_mmapped_page
,
1822 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1829 case TARGET_SYS_mprotect
:
1831 /* We only cover the case of linuxthreads mprotecting out
1832 its stack guard page and of dynamic loading mprotecting
1833 away the data (for some reason the whole library, then
1834 mprotects away the data part and mmap-FIX:es it again. */
1839 if (prot
!= TARGET_PROT_NONE
1840 || !is_mapped_only (sd
, &cris_cpu
->highest_mmapped_page
,
1841 addr
, (len
+ 8191) & ~8191))
1844 = cris_unknown_syscall (current_cpu
, pc
,
1845 "Unimplemented mprotect call "
1846 "(0x%lx, 0x%lx, 0x%lx)\n",
1847 (unsigned long) arg1
,
1848 (unsigned long) arg2
,
1849 (unsigned long) arg3
);
1853 /* Just ignore this. We could make this equal to munmap,
1854 but then we'd have to make sure no anon mmaps gets this
1855 address before a subsequent MAP_FIXED mmap intended to
1861 case TARGET_SYS_ioctl
:
1863 /* We support only a very limited functionality: checking
1864 stdout with TCGETS to perform the isatty function. The
1865 TCGETS ioctl isn't actually performed or the result used by
1866 an isatty () caller in a "hello, world" program; only the
1867 return value is then used. Maybe we shouldn't care about
1868 the environment of the simulator regarding isatty, but
1869 that's been working before, in the xsim simulator. */
1870 if (arg2
== TARGET_TCGETS
&& arg1
== 1)
1871 retval
= isatty (1) ? 0 : cb_host_to_target_errno (cb
, EINVAL
);
1873 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1877 case TARGET_SYS_munmap
:
1882 = unmap_pages (sd
, &cris_cpu
->highest_mmapped_page
, addr
,
1884 retval
= result
!= 0 ? -cb_host_to_target_errno (cb
, result
) : 0;
1888 case TARGET_SYS_wait4
:
1896 /* FIXME: We're not properly implementing __WCLONE, and we
1897 don't really need the special casing so we might as well
1898 make this general. */
1899 if ((!(pid
== (USI
) -1
1900 && options
== (TARGET___WCLONE
| TARGET_WNOHANG
)
1903 && (options
== TARGET___WCLONE
1904 || options
== TARGET___WALL
)))
1906 || cris_cpu
->thread_data
== NULL
)
1909 = cris_unknown_syscall (current_cpu
, pc
,
1910 "Unimplemented wait4 call "
1911 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1912 (unsigned long) arg1
,
1913 (unsigned long) arg2
,
1914 (unsigned long) arg3
,
1915 (unsigned long) arg4
);
1919 if (pid
== (USI
) -1)
1920 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1922 if (cris_cpu
->thread_data
[threadno
].threadid
1923 == cris_cpu
->thread_data
[i
].parent_threadid
1924 && cris_cpu
->thread_data
[i
].threadid
!= 0
1925 && cris_cpu
->thread_data
[i
].cpu_context
== NULL
)
1927 /* A zombied child. Get the exit value and clear the
1928 zombied entry so it will be reused. */
1929 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, saddr
,
1931 ->thread_data
[i
].exitval
);
1933 = cris_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1934 memset (&cris_cpu
->thread_data
[i
], 0,
1935 sizeof (cris_cpu
->thread_data
[i
]));
1941 /* We're waiting for a specific PID. If we don't find
1942 it zombied on this run, rerun the syscall. */
1943 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1944 if (pid
== cris_cpu
->thread_data
[i
].threadid
+ TARGET_PID
1945 && cris_cpu
->thread_data
[i
].cpu_context
== NULL
)
1948 /* Get the exit value if the caller wants it. */
1949 sim_core_write_unaligned_4 (current_cpu
, pc
, 0,
1952 ->thread_data
[i
].exitval
);
1955 = cris_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1956 memset (&cris_cpu
->thread_data
[i
], 0,
1957 sizeof (cris_cpu
->thread_data
[i
]));
1962 sim_pc_set (current_cpu
, pc
);
1965 retval
= -cb_host_to_target_errno (cb
, ECHILD
);
1970 case TARGET_SYS_rt_sigaction
:
1978 __sighandler_t sa_handler;
1979 unsigned long sa_flags;
1980 void (*sa_restorer)(void);
1986 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, old_sa
+ 0,
1987 cris_cpu
->sighandler
[signum
]);
1988 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 4, 0);
1989 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 8, 0);
1991 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
1992 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 12, 0);
1993 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 16, 0);
1997 USI target_sa_handler
1998 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
);
2000 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 4);
2001 USI target_sa_restorer
2002 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 8);
2003 USI target_sa_mask_low
2004 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 12);
2005 USI target_sa_mask_high
2006 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 16);
2008 /* We won't interrupt a syscall so we won't restart it,
2009 but a signal(2) call ends up syscalling rt_sigaction
2010 with this flag, so we have to handle it. The
2011 sa_restorer field contains garbage when not
2012 TARGET_SA_RESTORER, so don't look at it. For the
2013 time being, we don't nest sighandlers, so we
2014 ignore the sa_mask, which simplifies things. */
2015 if ((target_sa_flags
!= 0
2016 && target_sa_flags
!= TARGET_SA_RESTART
2017 && target_sa_flags
!= (TARGET_SA_RESTART
|TARGET_SA_SIGINFO
))
2018 || target_sa_handler
== 0)
2021 = cris_unknown_syscall (current_cpu
, pc
,
2022 "Unimplemented rt_sigaction "
2025 "[0x%x, 0x%x, 0x%x, "
2026 "{0x%x, 0x%x}], 0x%lx)\n",
2027 (unsigned long) arg1
,
2028 (unsigned long) arg2
,
2033 target_sa_mask_high
,
2034 (unsigned long) arg3
);
2038 cris_cpu
->sighandler
[signum
] = target_sa_handler
;
2040 /* Because we may have unblocked signals, one may now be
2041 pending, if there are threads, that is. */
2042 if (cris_cpu
->thread_data
)
2043 cris_cpu
->thread_data
[threadno
].sigpending
= 1;
2049 case TARGET_SYS_mremap
:
2055 USI new_addr
= arg5
;
2058 if (new_len
== old_len
)
2059 /* The program and/or library is possibly confused but
2060 this is a valid call. Happens with ipps-1.40 on file
2063 else if (new_len
< old_len
)
2065 /* Shrinking is easy. */
2066 if (unmap_pages (sd
, &cris_cpu
->highest_mmapped_page
,
2067 addr
+ new_len
, old_len
- new_len
) != 0)
2068 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2072 else if (! is_mapped (sd
, &cris_cpu
->highest_mmapped_page
,
2073 addr
+ old_len
, new_len
- old_len
))
2075 /* If the extension isn't mapped, we can just add it. */
2077 = create_map (sd
, &cris_cpu
->highest_mmapped_page
,
2078 addr
+ old_len
, new_len
- old_len
);
2080 if (mapped_addr
> (USI
) -8192)
2081 retval
= -cb_host_to_target_errno (cb
, -(SI
) mapped_addr
);
2085 else if (flags
& TARGET_MREMAP_MAYMOVE
)
2087 /* Create a whole new map and copy the contents
2088 block-by-block there. We ignore the new_addr argument
2091 USI prev_addr
= addr
;
2092 USI prev_len
= old_len
;
2095 = create_map (sd
, &cris_cpu
->highest_mmapped_page
,
2098 if (mapped_addr
> (USI
) -8192)
2100 retval
= -cb_host_to_target_errno (cb
, -(SI
) new_addr
);
2104 retval
= mapped_addr
;
2107 old_len
-= 8192, mapped_addr
+= 8192, addr
+= 8192)
2109 if (sim_core_read_buffer (sd
, current_cpu
, read_map
, buf
,
2111 || sim_core_write_buffer (sd
, current_cpu
, 0, buf
,
2112 mapped_addr
, 8192) != 8192)
2116 if (unmap_pages (sd
, &cris_cpu
->highest_mmapped_page
,
2117 prev_addr
, prev_len
) != 0)
2121 retval
= -cb_host_to_target_errno (cb
, -ENOMEM
);
2125 case TARGET_SYS_poll
:
2127 int npollfds
= arg2
;
2143 /* Check that this is the expected poll call from
2144 linuxthreads/manager.c; we don't support anything else.
2145 Remember, fd == 0 isn't supported. */
2147 || ((fd
= sim_core_read_unaligned_4 (current_cpu
, pc
,
2149 || ((events
= sim_core_read_unaligned_2 (current_cpu
, pc
,
2152 || ((cb
->to_fstat
) (cb
, fd
, &buf
) != 0
2153 || (buf
.st_mode
& S_IFIFO
) == 0)
2154 || cris_cpu
->thread_data
== NULL
)
2157 = cris_unknown_syscall (current_cpu
, pc
,
2158 "Unimplemented poll syscall "
2159 "(0x%lx: [0x%x, 0x%x, x], "
2161 (unsigned long) arg1
, fd
, events
,
2162 (unsigned long) arg2
,
2163 (unsigned long) arg3
);
2169 /* Iterate over threads; find a marker that a writer is
2170 sleeping, waiting for a reader. */
2171 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2172 if (cris_cpu
->thread_data
[i
].cpu_context
!= NULL
2173 && cris_cpu
->thread_data
[i
].pipe_read_fd
== fd
)
2175 revents
= TARGET_POLLIN
;
2180 /* Timeout decreases with whatever time passed between the
2181 last syscall and this. That's not exactly right for the
2182 first call, but it's close enough that it isn't
2183 worthwhile to complicate matters by making that a special
2186 -= (TARGET_TIME_MS (current_cpu
)
2187 - (cris_cpu
->thread_data
[threadno
].last_execution
));
2189 /* Arrange to repeat this syscall until timeout or event,
2190 decreasing timeout at each iteration. */
2191 if (timeout
> 0 && revents
== 0)
2193 bfd_byte timeout_buf
[4];
2195 bfd_putl32 (timeout
, timeout_buf
);
2196 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2197 H_GR_R12
, timeout_buf
, 4);
2198 sim_pc_set (current_cpu
, pc
);
2203 sim_core_write_unaligned_2 (current_cpu
, pc
, 0, ufds
+ 4 + 2,
2208 case TARGET_SYS_time
:
2210 retval
= (int) (*cb
->time
) (cb
);
2212 /* At time of this writing, CB_SYSCALL_time doesn't do the
2213 part of setting *arg1 to the return value. */
2215 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, retval
);
2219 case TARGET_SYS_gettimeofday
:
2222 USI ts
= TARGET_TIME (current_cpu
);
2223 USI tms
= TARGET_TIME_MS (current_cpu
);
2225 /* First dword is seconds since TARGET_EPOCH. */
2226 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, ts
);
2228 /* Second dword is microseconds. */
2229 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4,
2230 (tms
% 1000) * 1000);
2234 /* Time-zone info is always cleared. */
2235 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, 0);
2236 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, 0);
2241 case TARGET_SYS_llseek
:
2243 /* If it fits, tweak parameters to fit the "generic" 32-bit
2244 lseek and use that. */
2252 if (!((offs_hi
== 0 && offs_lo
>= 0)
2253 || (offs_hi
== -1 && offs_lo
< 0)))
2256 = cris_unknown_syscall (current_cpu
, pc
,
2257 "Unimplemented llseek offset,"
2258 " fd %d: 0x%x:0x%x\n",
2259 fd
, (unsigned) arg2
,
2264 s
.func
= TARGET_SYS_lseek
;
2267 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2269 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
2271 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2274 retval
= -s
.errcode
;
2277 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
,
2279 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
+ 4,
2280 s
.result
< 0 ? -1 : 0);
2285 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2288 void *iov_base; Starting address
2289 size_t iov_len; Number of bytes to transfer
2291 case TARGET_SYS_writev
:
2299 /* We'll ignore strict error-handling and just do multiple write calls. */
2300 for (i
= 0; i
< iovcnt
; i
++)
2304 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2307 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2310 s
.func
= TARGET_SYS_write
;
2315 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2317 sysret
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2319 if (sysret
!= iov_len
)
2334 /* This one does have a generic callback function, but at the time
2335 of this writing, cb_syscall does not have code for it, and we
2336 need target-specific code for the threads implementation
2338 case TARGET_SYS_kill
:
2345 /* At kill(2), glibc sets signal masks such that the thread
2346 machinery is initialized. Still, there is and was only
2348 if (cris_cpu
->max_threadid
== 0)
2350 if (pid
!= TARGET_PID
)
2352 retval
= -cb_host_to_target_errno (cb
, EPERM
);
2356 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2357 if (sig
== TARGET_SIGABRT
)
2358 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2359 the end-point for failing GCC test-cases. */
2360 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2364 sim_io_eprintf (sd
, "Unimplemented signal: %d\n", sig
);
2365 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2369 /* This will not be reached. */
2373 retval
= deliver_signal (current_cpu
, sig
, pid
);
2377 case TARGET_SYS_rt_sigprocmask
:
2384 if (how
!= TARGET_SIG_BLOCK
2385 && how
!= TARGET_SIG_SETMASK
2386 && how
!= TARGET_SIG_UNBLOCK
)
2389 = cris_unknown_syscall (current_cpu
, pc
,
2390 "Unimplemented rt_sigprocmask "
2391 "syscall (0x%x, 0x%x, 0x%x)\n",
2399 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2402 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2405 /* The sigmask is kept in the per-thread data, so we may
2406 need to create the first one. */
2407 if (cris_cpu
->thread_data
== NULL
)
2408 make_first_thread (current_cpu
);
2410 if (how
== TARGET_SIG_SETMASK
)
2411 for (i
= 0; i
< 64; i
++)
2412 cris_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
= 0;
2414 for (i
= 0; i
< 32; i
++)
2415 if ((set_low
& (1 << i
)))
2416 cris_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2417 = (how
!= TARGET_SIG_UNBLOCK
);
2419 for (i
= 0; i
< 31; i
++)
2420 if ((set_high
& (1 << i
)))
2421 cris_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2422 = (how
!= TARGET_SIG_UNBLOCK
);
2424 /* The mask changed, so a signal may be unblocked for
2426 cris_cpu
->thread_data
[threadno
].sigpending
= 1;
2434 for (i
= 0; i
< 32; i
++)
2435 if (cris_cpu
->thread_data
[threadno
]
2436 .sigdata
[i
+ 1].blocked
)
2438 for (i
= 0; i
< 31; i
++)
2439 if (cris_cpu
->thread_data
[threadno
]
2440 .sigdata
[i
+ 33].blocked
)
2443 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 0, set_low
);
2444 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 4, set_high
);
2451 case TARGET_SYS_sigreturn
:
2455 int was_sigsuspended
;
2457 if (cris_cpu
->thread_data
== NULL
2458 /* The CPU context is saved with the simulator data, not
2459 on the stack as in the real world. */
2460 || (cris_cpu
->thread_data
[threadno
].cpu_context_atsignal
2464 = cris_unknown_syscall (current_cpu
, pc
,
2465 "Invalid sigreturn syscall: "
2466 "no signal handler active "
2467 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2469 (unsigned long) arg1
,
2470 (unsigned long) arg2
,
2471 (unsigned long) arg3
,
2472 (unsigned long) arg4
,
2473 (unsigned long) arg5
,
2474 (unsigned long) arg6
);
2479 = cris_cpu
->thread_data
[threadno
].sigsuspended
;
2481 /* Restore the sigmask, either from the stack copy made when
2482 the sighandler was called, or from the saved state
2483 specifically for sigsuspend(2). */
2484 if (was_sigsuspended
)
2486 cris_cpu
->thread_data
[threadno
].sigsuspended
= 0;
2487 for (i
= 0; i
< 64; i
++)
2488 cris_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
2489 = cris_cpu
->thread_data
[threadno
]
2490 .sigdata
[i
].blocked_suspendsave
;
2498 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2499 H_GR_SP
, regbuf
, 4);
2500 sp
= bfd_getl32 (regbuf
);
2502 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
);
2504 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
+ 4);
2506 for (i
= 0; i
< 32; i
++)
2507 cris_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2508 = (set_low
& (1 << i
)) != 0;
2509 for (i
= 0; i
< 31; i
++)
2510 cris_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2511 = (set_high
& (1 << i
)) != 0;
2514 /* The mask changed, so a signal may be unblocked for
2516 cris_cpu
->thread_data
[threadno
].sigpending
= 1;
2518 memcpy (&cris_cpu
->cpu_data_placeholder
,
2519 cris_cpu
->thread_data
[threadno
].cpu_context_atsignal
,
2520 cris_cpu
->thread_cpu_data_size
);
2521 free (cris_cpu
->thread_data
[threadno
].cpu_context_atsignal
);
2522 cris_cpu
->thread_data
[threadno
].cpu_context_atsignal
= NULL
;
2524 /* The return value must come from the saved R10. */
2525 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, regbuf
, 4);
2526 retval
= bfd_getl32 (regbuf
);
2528 /* We must also break the "sigsuspension loop". */
2529 if (was_sigsuspended
)
2530 sim_pc_set (current_cpu
, sim_pc_get (current_cpu
) + 2);
2534 case TARGET_SYS_rt_sigsuspend
:
2542 = cris_unknown_syscall (current_cpu
, pc
,
2543 "Unimplemented rt_sigsuspend syscall"
2544 " arguments (0x%lx, 0x%lx)\n",
2545 (unsigned long) arg1
,
2546 (unsigned long) arg2
);
2550 /* Don't change the signal mask if we're already in
2551 sigsuspend state (i.e. this syscall is a rerun). */
2552 else if (!cris_cpu
->thread_data
[threadno
].sigsuspended
)
2555 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2558 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2562 /* Save the current sigmask and insert the user-supplied
2564 for (i
= 0; i
< 32; i
++)
2566 cris_cpu
->thread_data
[threadno
]
2567 .sigdata
[i
+ 1].blocked_suspendsave
2568 = cris_cpu
->thread_data
[threadno
]
2569 .sigdata
[i
+ 1].blocked
;
2571 cris_cpu
->thread_data
[threadno
]
2572 .sigdata
[i
+ 1].blocked
= (set_low
& (1 << i
)) != 0;
2574 for (i
= 0; i
< 31; i
++)
2576 cris_cpu
->thread_data
[threadno
]
2577 .sigdata
[i
+ 33].blocked_suspendsave
2578 = cris_cpu
->thread_data
[threadno
]
2579 .sigdata
[i
+ 33].blocked
;
2580 cris_cpu
->thread_data
[threadno
]
2581 .sigdata
[i
+ 33].blocked
= (set_high
& (1 << i
)) != 0;
2584 cris_cpu
->thread_data
[threadno
].sigsuspended
= 1;
2586 /* The mask changed, so a signal may be unblocked for
2588 cris_cpu
->thread_data
[threadno
].sigpending
= 1;
2591 /* Because we don't use arg1 (newsetp) when this syscall is
2592 rerun, it doesn't matter that we overwrite it with the
2593 (constant) return value. */
2594 retval
= -cb_host_to_target_errno (cb
, EINTR
);
2595 sim_pc_set (current_cpu
, pc
);
2599 /* Add case labels here for other syscalls using the 32-bit
2600 "struct stat", provided they have a corresponding simulator
2601 function of course. */
2602 case TARGET_SYS_stat
:
2603 case TARGET_SYS_fstat
:
2605 /* As long as the infrastructure doesn't cache anything
2606 related to the stat mapping, this trick gets us a dual
2607 "struct stat"-type mapping in the least error-prone way. */
2608 const char *saved_map
= cb
->stat_map
;
2609 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
2611 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_stat32_map
;
2612 cb
->stat_map
= stat32_map
;
2614 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2617 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2620 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2622 cb
->stat_map
= saved_map
;
2623 cb
->syscall_map
= saved_syscall_map
;
2627 case TARGET_SYS_getcwd
:
2632 char *cwd
= xmalloc (SIM_PATHMAX
);
2633 if (cwd
!= getcwd (cwd
, SIM_PATHMAX
))
2636 /* FIXME: When and if we support chdir, we need something
2637 a bit more elaborate. */
2638 if (simulator_sysroot
[0] != '\0')
2641 retval
= -cb_host_to_target_errno (cb
, ERANGE
);
2642 if (strlen (cwd
) + 1 <= size
)
2644 retval
= strlen (cwd
) + 1;
2645 if (sim_core_write_buffer (sd
, current_cpu
, 0, cwd
,
2647 != (unsigned int) retval
)
2648 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2654 case TARGET_SYS_access
:
2658 char *pbuf
= xmalloc (SIM_PATHMAX
);
2663 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2665 strcpy (pbuf
, simulator_sysroot
);
2666 o
+= strlen (simulator_sysroot
);
2669 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2672 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2673 if (pbuf
[i
+ o
] == 0)
2677 if (i
+ o
== SIM_PATHMAX
)
2679 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2683 /* Assert that we don't get calls for files for which we
2684 don't have support. */
2685 if (strncmp (pbuf
+ strlen (simulator_sysroot
),
2688 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2695 if (access (pbuf
, hmode
) != 0)
2696 retval
= -cb_host_to_target_errno (cb
, errno
);
2704 case TARGET_SYS_readlink
:
2709 char *pbuf
= xmalloc (SIM_PATHMAX
);
2710 char *lbuf
= xmalloc (SIM_PATHMAX
);
2711 char *lbuf_alloc
= lbuf
;
2716 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2718 strcpy (pbuf
, simulator_sysroot
);
2719 o
+= strlen (simulator_sysroot
);
2722 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2725 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2726 if (pbuf
[i
+ o
] == 0)
2730 if (i
+ o
== SIM_PATHMAX
)
2732 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2736 /* Intervene calls for certain files expected in the target
2737 proc file system. */
2738 if (strcmp (pbuf
+ strlen (simulator_sysroot
),
2739 "/proc/" XSTRING (TARGET_PID
) "/exe") == 0)
2742 = (STATE_PROG_ARGV (sd
) != NULL
2743 ? *STATE_PROG_ARGV (sd
) : NULL
);
2745 if (argv0
== NULL
|| *argv0
== '.')
2748 = cris_unknown_syscall (current_cpu
, pc
,
2749 "Unimplemented readlink syscall "
2750 "(0x%lx: [\"%s\"], 0x%lx)\n",
2751 (unsigned long) arg1
, pbuf
,
2752 (unsigned long) arg2
);
2755 else if (*argv0
== '/')
2757 if (strncmp (simulator_sysroot
, argv0
,
2758 strlen (simulator_sysroot
)) == 0)
2759 argv0
+= strlen (simulator_sysroot
);
2761 strcpy (lbuf
, argv0
);
2762 nchars
= strlen (argv0
) + 1;
2766 if (getcwd (lbuf
, SIM_PATHMAX
) != NULL
2767 && strlen (lbuf
) + 2 + strlen (argv0
) < SIM_PATHMAX
)
2769 if (strncmp (simulator_sysroot
, lbuf
,
2770 strlen (simulator_sysroot
)) == 0)
2771 lbuf
+= strlen (simulator_sysroot
);
2774 strcat (lbuf
, argv0
);
2775 nchars
= strlen (lbuf
) + 1;
2782 nchars
= readlink (pbuf
, lbuf
, SIM_PATHMAX
);
2784 /* We trust that the readlink result returns a *relative*
2785 link, or one already adjusted for the file-path-prefix.
2786 (We can't generally tell the difference, so we go with
2787 the easiest decision; no adjustment.) */
2791 retval
= -cb_host_to_target_errno (cb
, errno
);
2795 if (bufsiz
< nchars
)
2798 if (sim_core_write_buffer (sd
, current_cpu
, write_map
, lbuf
,
2799 buf
, nchars
) != (unsigned int) nchars
)
2800 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2809 case TARGET_SYS_sched_getscheduler
:
2813 /* FIXME: Search (other) existing threads. */
2814 if (pid
!= 0 && pid
!= TARGET_PID
)
2815 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2817 retval
= TARGET_SCHED_OTHER
;
2821 case TARGET_SYS_sched_getparam
:
2827 struct sched_param {
2831 if (pid
!= 0 && pid
!= TARGET_PID
)
2832 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2835 /* FIXME: Save scheduler setting before threads are
2837 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, paramp
,
2838 cris_cpu
->thread_data
!= NULL
2840 ->thread_data
[threadno
]
2848 case TARGET_SYS_sched_setparam
:
2853 if ((pid
!= 0 && pid
!= TARGET_PID
)
2854 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2856 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2862 case TARGET_SYS_sched_setscheduler
:
2868 if ((pid
!= 0 && pid
!= TARGET_PID
)
2869 || policy
!= TARGET_SCHED_OTHER
2870 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2872 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2874 /* FIXME: Save scheduler setting to be read in later
2875 sched_getparam calls. */
2880 case TARGET_SYS_sched_yield
:
2881 /* We reschedule to the next thread after a syscall anyway, so
2882 we don't have to do anything here than to set the return
2887 case TARGET_SYS_sched_get_priority_min
:
2888 case TARGET_SYS_sched_get_priority_max
:
2890 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2895 case TARGET_SYS_ugetrlimit
:
2897 unsigned int curlim
, maxlim
;
2898 if (arg1
!= TARGET_RLIMIT_STACK
&& arg1
!= TARGET_RLIMIT_NOFILE
)
2900 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2906 unsigned long rlim_cur;
2907 unsigned long rlim_max;
2909 if (arg1
== TARGET_RLIMIT_NOFILE
)
2911 /* Sadly a very low limit. Better not lie, though. */
2912 maxlim
= curlim
= MAX_CALLBACK_FDS
;
2914 else /* arg1 == TARGET_RLIMIT_STACK */
2916 maxlim
= 0xffffffff;
2919 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, curlim
);
2920 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, maxlim
);
2925 case TARGET_SYS_setrlimit
:
2926 if (arg1
!= TARGET_RLIMIT_STACK
)
2928 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2931 /* FIXME: Save values for future ugetrlimit calls. */
2935 /* Provide a very limited subset of the sysctl functions, and
2936 abort for the rest. */
2937 case TARGET_SYS__sysctl
:
2940 struct __sysctl_args {
2947 unsigned long __unused[4];
2949 SI name
= sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
);
2950 SI name0
= name
== 0
2951 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
);
2952 SI name1
= name
== 0
2953 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
+ 4);
2955 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4);
2957 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 8);
2959 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 12);
2960 SI oldlen
= oldlenp
== 0
2961 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, oldlenp
);
2963 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 16);
2965 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 20);
2967 if (name0
== TARGET_CTL_KERN
&& name1
== TARGET_CTL_KERN_VERSION
)
2969 SI to_write
= oldlen
< (SI
) sizeof (TARGET_UTSNAME
)
2970 ? oldlen
: (SI
) sizeof (TARGET_UTSNAME
);
2972 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldlenp
,
2973 sizeof (TARGET_UTSNAME
));
2975 if (sim_core_write_buffer (sd
, current_cpu
, write_map
,
2976 TARGET_UTSNAME
, oldval
,
2978 != (unsigned int) to_write
)
2979 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2986 = cris_unknown_syscall (current_cpu
, pc
,
2987 "Unimplemented _sysctl syscall "
2988 "(0x%lx: [0x%lx, 0x%lx],"
2989 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
2990 (unsigned long) name
,
2991 (unsigned long) name0
,
2992 (unsigned long) name1
,
2993 (unsigned long) nlen
,
2994 (unsigned long) oldval
,
2995 (unsigned long) oldlenp
,
2996 (unsigned long) newval
,
2997 (unsigned long) newlen
);
3001 case TARGET_SYS_exit
:
3003 /* Here for all but the last thread. */
3006 = cris_cpu
->thread_data
[threadno
].threadid
+ TARGET_PID
;
3008 = (cris_cpu
->thread_data
[threadno
].parent_threadid
3010 int exitsig
= cris_cpu
->thread_data
[threadno
].exitsig
;
3012 /* Any children are now all orphans. */
3013 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3014 if (cris_cpu
->thread_data
[i
].parent_threadid
3015 == cris_cpu
->thread_data
[threadno
].threadid
)
3016 /* Make getppid(2) return 1 for them, poor little ones. */
3017 cris_cpu
->thread_data
[i
].parent_threadid
= -TARGET_PID
+ 1;
3019 /* Free the cpu context data. When the parent has received
3020 the exit status, we'll clear the entry too. */
3021 free (cris_cpu
->thread_data
[threadno
].cpu_context
);
3022 cris_cpu
->thread_data
[threadno
].cpu_context
= NULL
;
3023 cris_cpu
->m1threads
--;
3026 sim_io_eprintf (sd
, "Thread %d exited with status %d\n",
3028 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
3032 /* Still, we may want to support non-zero exit values. */
3033 cris_cpu
->thread_data
[threadno
].exitval
= arg1
<< 8;
3036 deliver_signal (current_cpu
, exitsig
, ppid
);
3040 case TARGET_SYS_clone
:
3042 int nthreads
= cris_cpu
->m1threads
+ 1;
3043 void *thread_cpu_data
;
3044 bfd_byte old_sp_buf
[4];
3046 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3049 /* That's right, the syscall clone arguments are reversed
3050 compared to sys_clone notes in clone(2) and compared to
3051 other Linux ports (i.e. it's the same order as in the
3052 clone(2) libcall). */
3056 if (nthreads
== SIM_TARGET_MAX_THREADS
)
3058 retval
= -cb_host_to_target_errno (cb
, EAGAIN
);
3062 /* FIXME: Implement the low byte. */
3063 if ((flags
& ~TARGET_CSIGNAL
) !=
3066 | TARGET_CLONE_FILES
3067 | TARGET_CLONE_SIGHAND
)
3071 = cris_unknown_syscall (current_cpu
, pc
,
3072 "Unimplemented clone syscall "
3074 (unsigned long) arg1
,
3075 (unsigned long) arg2
);
3079 if (cris_cpu
->thread_data
== NULL
)
3080 make_first_thread (current_cpu
);
3082 /* The created thread will get the new SP and a cleared R10.
3083 Since it's created out of a copy of the old thread and we
3084 don't have a set-register-function that just take the
3085 cpu_data as a parameter, we set the childs values first,
3086 and write back or overwrite them in the parent after the
3088 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
3089 H_GR_SP
, old_sp_buf
, 4);
3090 bfd_putl32 (newsp
, sp_buf
);
3091 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3092 H_GR_SP
, sp_buf
, 4);
3093 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3094 H_GR_R10
, (bfd_byte
*) zeros
, 4);
3097 ->make_thread_cpu_data
) (current_cpu
,
3098 &cris_cpu
->cpu_data_placeholder
);
3099 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3100 H_GR_SP
, old_sp_buf
, 4);
3102 retval
= ++cris_cpu
->max_threadid
+ TARGET_PID
;
3104 /* Find an unused slot. After a few threads have been created
3105 and exited, the array is expected to be a bit fragmented.
3106 We don't reuse the first entry, though, that of the
3108 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
3109 if (cris_cpu
->thread_data
[i
].cpu_context
== NULL
3110 /* Don't reuse a zombied entry. */
3111 && cris_cpu
->thread_data
[i
].threadid
== 0)
3114 memcpy (&cris_cpu
->thread_data
[i
],
3115 &cris_cpu
->thread_data
[threadno
],
3116 sizeof (cris_cpu
->thread_data
[i
]));
3117 cris_cpu
->thread_data
[i
].cpu_context
= thread_cpu_data
;
3118 cris_cpu
->thread_data
[i
].cpu_context_atsignal
= NULL
;
3119 cris_cpu
->thread_data
[i
].threadid
= cris_cpu
->max_threadid
;
3120 cris_cpu
->thread_data
[i
].parent_threadid
3121 = cris_cpu
->thread_data
[threadno
].threadid
;
3122 cris_cpu
->thread_data
[i
].pipe_read_fd
= 0;
3123 cris_cpu
->thread_data
[i
].pipe_write_fd
= 0;
3124 cris_cpu
->thread_data
[i
].at_syscall
= 0;
3125 cris_cpu
->thread_data
[i
].sigpending
= 0;
3126 cris_cpu
->thread_data
[i
].sigsuspended
= 0;
3127 cris_cpu
->thread_data
[i
].exitsig
= flags
& TARGET_CSIGNAL
;
3128 cris_cpu
->m1threads
= nthreads
;
3132 /* Better watch these in case they do something necessary. */
3133 case TARGET_SYS_socketcall
:
3134 retval
= -cb_host_to_target_errno (cb
, ENOSYS
);
3137 case TARGET_SYS_set_thread_area
:
3138 /* Do the same error check as Linux. */
3141 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
3144 (*cris_cpu
->set_target_thread_data
) (current_cpu
, arg1
);
3148 unimplemented_syscall
:
3151 = cris_unknown_syscall (current_cpu
, pc
,
3152 "Unimplemented syscall: %d "
3153 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3154 callnum
, arg1
, arg2
, arg3
, arg4
, arg5
,
3159 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
3160 if (callnum
== TARGET_SYS_open
)
3162 cris_cpu
->last_open_fd
= retval
;
3163 cris_cpu
->last_open_flags
= arg2
;
3166 cris_cpu
->last_syscall
= callnum
;
3168 /* A system call is a rescheduling point. For the time being, we don't
3169 reschedule anywhere else. */
3170 if (cris_cpu
->m1threads
!= 0
3171 /* We need to schedule off from an exiting thread that is the
3173 || (cris_cpu
->thread_data
!= NULL
3174 && cris_cpu
->thread_data
[threadno
].cpu_context
== NULL
))
3176 bfd_byte retval_buf
[4];
3178 cris_cpu
->thread_data
[threadno
].last_execution
3179 = TARGET_TIME_MS (current_cpu
);
3180 bfd_putl32 (retval
, retval_buf
);
3181 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3183 cris_cpu
->thread_data
[threadno
].at_syscall
= 1;
3184 reschedule (current_cpu
);
3186 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3187 retval
= bfd_getl32 (retval_buf
);
3193 /* Callback from simulator write saying that the pipe at (reader, writer)
3194 is now non-empty (so the writer should wait until the pipe is empty, at
3195 least not write to this or any other pipe). Simplest is to just wait
3196 until the pipe is empty. */
3199 cris_pipe_nonempty (host_callback
*cb ATTRIBUTE_UNUSED
,
3200 int reader
, int writer
)
3202 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3203 struct cris_sim_cpu
*cris_cpu
= CRIS_SIM_CPU (cpu
);
3204 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3206 /* It's the current thread: we just have to re-run the current
3207 syscall instruction (presumably "break 13") and change the syscall
3208 to the special simulator-wait code. Oh, and set a marker that
3209 we're waiting, so we can disambiguate the special call from a
3212 This function may be called multiple times between cris_pipe_empty,
3213 but we must avoid e.g. decreasing PC every time. Check fd markers
3215 if (cris_cpu
->thread_data
== NULL
)
3217 sim_io_eprintf (CPU_STATE (cpu
),
3218 "Terminating simulation due to writing pipe rd:wr %d:%d"
3219 " from one single thread\n", reader
, writer
);
3220 sim_engine_halt (CPU_STATE (cpu
), cpu
,
3221 NULL
, sim_pc_get (cpu
), sim_stopped
, SIM_SIGILL
);
3223 else if (cris_cpu
->thread_data
[cris_cpu
->threadno
].pipe_write_fd
== 0)
3225 cris_cpu
->thread_data
[cris_cpu
->threadno
].pipe_write_fd
= writer
;
3226 cris_cpu
->thread_data
[cris_cpu
->threadno
].pipe_read_fd
= reader
;
3227 /* FIXME: We really shouldn't change registers other than R10 in
3228 syscalls (like R9), here or elsewhere. */
3229 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R9
, (bfd_byte
*) zeros
, 4);
3230 sim_pc_set (cpu
, sim_pc_get (cpu
) - 2);
3234 /* Callback from simulator close or read call saying that the pipe at
3235 (reader, writer) is now empty (so the writer can write again, perhaps
3236 leave a waiting state). If there are bytes remaining, they couldn't be
3237 consumed (perhaps due to the pipe closing). */
3240 cris_pipe_empty (host_callback
*cb
,
3245 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3246 struct cris_sim_cpu
*cris_cpu
= CRIS_SIM_CPU (cpu
);
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 (cris_cpu
->thread_data
[i
].cpu_context
3255 && cris_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 (cris_cpu
->thread_data
[cris_cpu
->threadno
].cpu_context
,
3263 &cris_cpu
->cpu_data_placeholder
,
3264 cris_cpu
->thread_cpu_data_size
);
3265 memcpy (&cris_cpu
->cpu_data_placeholder
,
3266 cris_cpu
->thread_data
[i
].cpu_context
,
3267 cris_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 (cris_cpu
->thread_data
[i
].cpu_context
,
3290 &cris_cpu
->cpu_data_placeholder
,
3291 cris_cpu
->thread_cpu_data_size
);
3292 memcpy (&cris_cpu
->cpu_data_placeholder
,
3293 cris_cpu
->thread_data
[cris_cpu
->threadno
].cpu_context
,
3294 cris_cpu
->thread_cpu_data_size
);
3295 cris_cpu
->thread_data
[i
].pipe_read_fd
= 0;
3296 cris_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
,