1 /* CRIS exception, interrupt, and trap (EIT) support
2 Copyright (C) 2004-2021 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/callback.h"
29 /* FIXME: get rid of targ-vals.h usage everywhere else. */
40 #ifdef HAVE_SYS_PARAM_H
41 #include <sys/param.h>
43 #ifdef HAVE_SYS_STAT_H
46 /* For PATH_MAX, originally. */
51 /* From ld/sysdep.h. */
53 # define SIM_PATHMAX PATH_MAX
56 # define SIM_PATHMAX MAXPATHLEN
58 # define SIM_PATHMAX 1024
62 /* The verbatim values are from asm-cris/unistd.h. */
64 #define TARGET_SYS_exit 1
65 #define TARGET_SYS_read 3
66 #define TARGET_SYS_write 4
67 #define TARGET_SYS_open 5
68 #define TARGET_SYS_close 6
69 #define TARGET_SYS_unlink 10
70 #define TARGET_SYS_time 13
71 #define TARGET_SYS_lseek 19
72 #define TARGET_SYS_getpid 20
73 #define TARGET_SYS_access 33
74 #define TARGET_SYS_kill 37
75 #define TARGET_SYS_rename 38
76 #define TARGET_SYS_pipe 42
77 #define TARGET_SYS_brk 45
78 #define TARGET_SYS_ioctl 54
79 #define TARGET_SYS_fcntl 55
80 #define TARGET_SYS_getppid 64
81 #define TARGET_SYS_setrlimit 75
82 #define TARGET_SYS_gettimeofday 78
83 #define TARGET_SYS_readlink 85
84 #define TARGET_SYS_munmap 91
85 #define TARGET_SYS_truncate 92
86 #define TARGET_SYS_ftruncate 93
87 #define TARGET_SYS_socketcall 102
88 #define TARGET_SYS_stat 106
89 #define TARGET_SYS_fstat 108
90 #define TARGET_SYS_wait4 114
91 #define TARGET_SYS_sigreturn 119
92 #define TARGET_SYS_clone 120
93 #define TARGET_SYS_uname 122
94 #define TARGET_SYS_mprotect 125
95 #define TARGET_SYS_llseek 140
96 #define TARGET_SYS_writev 146
97 #define TARGET_SYS__sysctl 149
98 #define TARGET_SYS_sched_setparam 154
99 #define TARGET_SYS_sched_getparam 155
100 #define TARGET_SYS_sched_setscheduler 156
101 #define TARGET_SYS_sched_getscheduler 157
102 #define TARGET_SYS_sched_yield 158
103 #define TARGET_SYS_sched_get_priority_max 159
104 #define TARGET_SYS_sched_get_priority_min 160
105 #define TARGET_SYS_mremap 163
106 #define TARGET_SYS_poll 168
107 #define TARGET_SYS_rt_sigaction 174
108 #define TARGET_SYS_rt_sigprocmask 175
109 #define TARGET_SYS_rt_sigsuspend 179
110 #define TARGET_SYS_getcwd 183
111 #define TARGET_SYS_ugetrlimit 191
112 #define TARGET_SYS_mmap2 192
113 #define TARGET_SYS_stat64 195
114 #define TARGET_SYS_lstat64 196
115 #define TARGET_SYS_fstat64 197
116 #define TARGET_SYS_geteuid32 201
117 #define TARGET_SYS_getuid32 199
118 #define TARGET_SYS_getegid32 202
119 #define TARGET_SYS_getgid32 200
120 #define TARGET_SYS_fcntl64 221
121 #define TARGET_SYS_set_thread_area 243
122 #define TARGET_SYS_exit_group 252
124 #define TARGET_PROT_READ 0x1
125 #define TARGET_PROT_WRITE 0x2
126 #define TARGET_PROT_EXEC 0x4
127 #define TARGET_PROT_NONE 0x0
129 #define TARGET_MAP_SHARED 0x01
130 #define TARGET_MAP_PRIVATE 0x02
131 #define TARGET_MAP_TYPE 0x0f
132 #define TARGET_MAP_FIXED 0x10
133 #define TARGET_MAP_ANONYMOUS 0x20
134 #define TARGET_MAP_DENYWRITE 0x800
136 #define TARGET_CTL_KERN 1
137 #define TARGET_CTL_VM 2
138 #define TARGET_CTL_NET 3
139 #define TARGET_CTL_PROC 4
140 #define TARGET_CTL_FS 5
141 #define TARGET_CTL_DEBUG 6
142 #define TARGET_CTL_DEV 7
143 #define TARGET_CTL_BUS 8
144 #define TARGET_CTL_ABI 9
146 #define TARGET_CTL_KERN_VERSION 4
149 #define TARGET_MREMAP_MAYMOVE 1
150 #define TARGET_MREMAP_FIXED 2
152 #define TARGET_TCGETS 0x5401
154 #define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
156 /* Seconds since 1970-01-01 to the above date + 10 minutes;
157 'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'. */
158 #define TARGET_EPOCH 1230764410
160 /* Milliseconds since start of run. We use the number of syscalls to
161 avoid introducing noise in the execution time. */
162 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
164 /* Seconds as in time(2). */
165 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
167 #define TARGET_SCHED_OTHER 0
169 #define TARGET_RLIMIT_STACK 3
170 #define TARGET_RLIMIT_NOFILE 7
172 #define SIM_TARGET_MAX_THREADS 64
173 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
175 /* From linux/sched.h. */
176 #define TARGET_CSIGNAL 0x000000ff
177 #define TARGET_CLONE_VM 0x00000100
178 #define TARGET_CLONE_FS 0x00000200
179 #define TARGET_CLONE_FILES 0x00000400
180 #define TARGET_CLONE_SIGHAND 0x00000800
181 #define TARGET_CLONE_PID 0x00001000
182 #define TARGET_CLONE_PTRACE 0x00002000
183 #define TARGET_CLONE_VFORK 0x00004000
184 #define TARGET_CLONE_PARENT 0x00008000
185 #define TARGET_CLONE_THREAD 0x00010000
186 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
188 /* From asm-cris/poll.h. */
189 #define TARGET_POLLIN 1
191 /* From asm-cris/signal.h. */
192 #define TARGET_SIG_BLOCK 0
193 #define TARGET_SIG_UNBLOCK 1
194 #define TARGET_SIG_SETMASK 2
196 #define TARGET_SIG_DFL 0
197 #define TARGET_SIG_IGN 1
198 #define TARGET_SIG_ERR ((USI)-1)
200 #define TARGET_SIGHUP 1
201 #define TARGET_SIGINT 2
202 #define TARGET_SIGQUIT 3
203 #define TARGET_SIGILL 4
204 #define TARGET_SIGTRAP 5
205 #define TARGET_SIGABRT 6
206 #define TARGET_SIGIOT 6
207 #define TARGET_SIGBUS 7
208 #define TARGET_SIGFPE 8
209 #define TARGET_SIGKILL 9
210 #define TARGET_SIGUSR1 10
211 #define TARGET_SIGSEGV 11
212 #define TARGET_SIGUSR2 12
213 #define TARGET_SIGPIPE 13
214 #define TARGET_SIGALRM 14
215 #define TARGET_SIGTERM 15
216 #define TARGET_SIGSTKFLT 16
217 #define TARGET_SIGCHLD 17
218 #define TARGET_SIGCONT 18
219 #define TARGET_SIGSTOP 19
220 #define TARGET_SIGTSTP 20
221 #define TARGET_SIGTTIN 21
222 #define TARGET_SIGTTOU 22
223 #define TARGET_SIGURG 23
224 #define TARGET_SIGXCPU 24
225 #define TARGET_SIGXFSZ 25
226 #define TARGET_SIGVTALRM 26
227 #define TARGET_SIGPROF 27
228 #define TARGET_SIGWINCH 28
229 #define TARGET_SIGIO 29
230 #define TARGET_SIGPOLL SIGIO
231 /* Actually commented out in the kernel header. */
232 #define TARGET_SIGLOST 29
233 #define TARGET_SIGPWR 30
234 #define TARGET_SIGSYS 31
236 /* From include/asm-cris/signal.h. */
237 #define TARGET_SA_NOCLDSTOP 0x00000001
238 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
239 #define TARGET_SA_SIGINFO 0x00000004
240 #define TARGET_SA_ONSTACK 0x08000000
241 #define TARGET_SA_RESTART 0x10000000
242 #define TARGET_SA_NODEFER 0x40000000
243 #define TARGET_SA_RESETHAND 0x80000000
244 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
245 #define TARGET_SA_RESTORER 0x04000000
247 /* From linux/wait.h. */
248 #define TARGET_WNOHANG 1
249 #define TARGET_WUNTRACED 2
250 #define TARGET___WNOTHREAD 0x20000000
251 #define TARGET___WALL 0x40000000
252 #define TARGET___WCLONE 0x80000000
254 /* From linux/limits.h. */
255 #define TARGET_PIPE_BUF 4096
258 #define TARGET_R_OK 4
259 #define TARGET_W_OK 2
260 #define TARGET_X_OK 1
261 #define TARGET_F_OK 0
263 static const char stat_map
[] =
264 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
265 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
266 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
269 static const CB_TARGET_DEFS_MAP syscall_map
[] =
271 { "open", CB_SYS_open
, TARGET_SYS_open
},
272 { "close", CB_SYS_close
, TARGET_SYS_close
},
273 { "read", CB_SYS_read
, TARGET_SYS_read
},
274 { "write", CB_SYS_write
, TARGET_SYS_write
},
275 { "lseek", CB_SYS_lseek
, TARGET_SYS_lseek
},
276 { "unlink", CB_SYS_unlink
, TARGET_SYS_unlink
},
277 { "getpid", CB_SYS_getpid
, TARGET_SYS_getpid
},
278 { "fstat", CB_SYS_fstat
, TARGET_SYS_fstat64
},
279 { "lstat", CB_SYS_lstat
, TARGET_SYS_lstat64
},
280 { "stat", CB_SYS_stat
, TARGET_SYS_stat64
},
281 { "pipe", CB_SYS_pipe
, TARGET_SYS_pipe
},
282 { "rename", CB_SYS_rename
, TARGET_SYS_rename
},
283 { "truncate", CB_SYS_truncate
, TARGET_SYS_truncate
},
284 { "ftruncate", CB_SYS_ftruncate
, TARGET_SYS_ftruncate
},
288 /* An older, 32-bit-only stat mapping. */
289 static const char stat32_map
[] =
290 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
291 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
292 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
294 /* Map for calls using the 32-bit struct stat. Primarily used by the
295 newlib Linux mapping. */
296 static const CB_TARGET_DEFS_MAP syscall_stat32_map
[] =
298 { "fstat", CB_SYS_fstat
, TARGET_SYS_fstat
},
299 { "stat", CB_SYS_stat
, TARGET_SYS_stat
},
303 /* Giving the true value for the running sim process will lead to
304 non-time-invariant behavior. */
305 #define TARGET_PID 42
307 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
308 we did, we'd still don't get a register number with the "16" offset. */
309 #define TARGET_SRP_REGNUM (16+11)
311 /* Extracted by applying
312 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
313 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
314 adjusting the synonyms. */
316 static const CB_TARGET_DEFS_MAP errno_map
[] =
319 { "EPERM", EPERM
, 1 },
322 { "ENOENT", ENOENT
, 2 },
325 { "ESRCH", ESRCH
, 3 },
328 { "EINTR", EINTR
, 4 },
334 { "ENXIO", ENXIO
, 6 },
337 { "E2BIG", E2BIG
, 7 },
340 { "ENOEXEC", ENOEXEC
, 8 },
343 { "EBADF", EBADF
, 9 },
346 { "ECHILD", ECHILD
, 10 },
349 { "EAGAIN", EAGAIN
, 11 },
352 { "ENOMEM", ENOMEM
, 12 },
355 { "EACCES", EACCES
, 13 },
358 { "EFAULT", EFAULT
, 14 },
361 { "ENOTBLK", ENOTBLK
, 15 },
364 { "EBUSY", EBUSY
, 16 },
367 { "EEXIST", EEXIST
, 17 },
370 { "EXDEV", EXDEV
, 18 },
373 { "ENODEV", ENODEV
, 19 },
376 { "ENOTDIR", ENOTDIR
, 20 },
379 { "EISDIR", EISDIR
, 21 },
382 { "EINVAL", EINVAL
, 22 },
385 { "ENFILE", ENFILE
, 23 },
388 { "EMFILE", EMFILE
, 24 },
391 { "ENOTTY", ENOTTY
, 25 },
394 { "ETXTBSY", ETXTBSY
, 26 },
397 { "EFBIG", EFBIG
, 27 },
400 { "ENOSPC", ENOSPC
, 28 },
403 { "ESPIPE", ESPIPE
, 29 },
406 { "EROFS", EROFS
, 30 },
409 { "EMLINK", EMLINK
, 31 },
412 { "EPIPE", EPIPE
, 32 },
415 { "EDOM", EDOM
, 33 },
418 { "ERANGE", ERANGE
, 34 },
421 { "EDEADLK", EDEADLK
, 35 },
424 { "ENAMETOOLONG", ENAMETOOLONG
, 36 },
427 { "ENOLCK", ENOLCK
, 37 },
430 { "ENOSYS", ENOSYS
, 38 },
433 { "ENOTEMPTY", ENOTEMPTY
, 39 },
436 { "ELOOP", ELOOP
, 40 },
439 { "EWOULDBLOCK", EWOULDBLOCK
, 11 },
442 { "ENOMSG", ENOMSG
, 42 },
445 { "EIDRM", EIDRM
, 43 },
448 { "ECHRNG", ECHRNG
, 44 },
451 { "EL2NSYNC", EL2NSYNC
, 45 },
454 { "EL3HLT", EL3HLT
, 46 },
457 { "EL3RST", EL3RST
, 47 },
460 { "ELNRNG", ELNRNG
, 48 },
463 { "EUNATCH", EUNATCH
, 49 },
466 { "ENOCSI", ENOCSI
, 50 },
469 { "EL2HLT", EL2HLT
, 51 },
472 { "EBADE", EBADE
, 52 },
475 { "EBADR", EBADR
, 53 },
478 { "EXFULL", EXFULL
, 54 },
481 { "ENOANO", ENOANO
, 55 },
484 { "EBADRQC", EBADRQC
, 56 },
487 { "EBADSLT", EBADSLT
, 57 },
490 { "EDEADLOCK", EDEADLOCK
, 35 },
493 { "EBFONT", EBFONT
, 59 },
496 { "ENOSTR", ENOSTR
, 60 },
499 { "ENODATA", ENODATA
, 61 },
502 { "ETIME", ETIME
, 62 },
505 { "ENOSR", ENOSR
, 63 },
508 { "ENONET", ENONET
, 64 },
511 { "ENOPKG", ENOPKG
, 65 },
514 { "EREMOTE", EREMOTE
, 66 },
517 { "ENOLINK", ENOLINK
, 67 },
520 { "EADV", EADV
, 68 },
523 { "ESRMNT", ESRMNT
, 69 },
526 { "ECOMM", ECOMM
, 70 },
529 { "EPROTO", EPROTO
, 71 },
532 { "EMULTIHOP", EMULTIHOP
, 72 },
535 { "EDOTDOT", EDOTDOT
, 73 },
538 { "EBADMSG", EBADMSG
, 74 },
541 { "EOVERFLOW", EOVERFLOW
, 75 },
544 { "ENOTUNIQ", ENOTUNIQ
, 76 },
547 { "EBADFD", EBADFD
, 77 },
550 { "EREMCHG", EREMCHG
, 78 },
553 { "ELIBACC", ELIBACC
, 79 },
556 { "ELIBBAD", ELIBBAD
, 80 },
559 { "ELIBSCN", ELIBSCN
, 81 },
562 { "ELIBMAX", ELIBMAX
, 82 },
565 { "ELIBEXEC", ELIBEXEC
, 83 },
568 { "EILSEQ", EILSEQ
, 84 },
571 { "ERESTART", ERESTART
, 85 },
574 { "ESTRPIPE", ESTRPIPE
, 86 },
577 { "EUSERS", EUSERS
, 87 },
580 { "ENOTSOCK", ENOTSOCK
, 88 },
583 { "EDESTADDRREQ", EDESTADDRREQ
, 89 },
586 { "EMSGSIZE", EMSGSIZE
, 90 },
589 { "EPROTOTYPE", EPROTOTYPE
, 91 },
592 { "ENOPROTOOPT", ENOPROTOOPT
, 92 },
594 #ifdef EPROTONOSUPPORT
595 { "EPROTONOSUPPORT", EPROTONOSUPPORT
, 93 },
597 #ifdef ESOCKTNOSUPPORT
598 { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT
, 94 },
601 { "EOPNOTSUPP", EOPNOTSUPP
, 95 },
604 { "EPFNOSUPPORT", EPFNOSUPPORT
, 96 },
607 { "EAFNOSUPPORT", EAFNOSUPPORT
, 97 },
610 { "EADDRINUSE", EADDRINUSE
, 98 },
613 { "EADDRNOTAVAIL", EADDRNOTAVAIL
, 99 },
616 { "ENETDOWN", ENETDOWN
, 100 },
619 { "ENETUNREACH", ENETUNREACH
, 101 },
622 { "ENETRESET", ENETRESET
, 102 },
625 { "ECONNABORTED", ECONNABORTED
, 103 },
628 { "ECONNRESET", ECONNRESET
, 104 },
631 { "ENOBUFS", ENOBUFS
, 105 },
634 { "EISCONN", EISCONN
, 106 },
637 { "ENOTCONN", ENOTCONN
, 107 },
640 { "ESHUTDOWN", ESHUTDOWN
, 108 },
643 { "ETOOMANYREFS", ETOOMANYREFS
, 109 },
646 { "ETIMEDOUT", ETIMEDOUT
, 110 },
649 { "ECONNREFUSED", ECONNREFUSED
, 111 },
652 { "EHOSTDOWN", EHOSTDOWN
, 112 },
655 { "EHOSTUNREACH", EHOSTUNREACH
, 113 },
658 { "EALREADY", EALREADY
, 114 },
661 { "EINPROGRESS", EINPROGRESS
, 115 },
664 { "ESTALE", ESTALE
, 116 },
667 { "EUCLEAN", EUCLEAN
, 117 },
670 { "ENOTNAM", ENOTNAM
, 118 },
673 { "ENAVAIL", ENAVAIL
, 119 },
676 { "EISNAM", EISNAM
, 120 },
679 { "EREMOTEIO", EREMOTEIO
, 121 },
682 { "EDQUOT", EDQUOT
, 122 },
685 { "ENOMEDIUM", ENOMEDIUM
, 123 },
688 { "EMEDIUMTYPE", EMEDIUMTYPE
, 124 },
693 /* Extracted by applying
694 perl -ne 'if ($_ =~ /^#define/) { split;
695 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
696 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
697 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
698 installation and removing synonyms and unnecessary items. Don't
699 forget the end-marker. */
701 /* These we treat specially, as they're used in the fcntl F_GETFL
702 syscall. For consistency, open_map is also manually edited to use
704 #define TARGET_O_ACCMODE 0x3
705 #define TARGET_O_RDONLY 0x0
706 #define TARGET_O_WRONLY 0x1
708 static const CB_TARGET_DEFS_MAP open_map
[] = {
710 { "O_ACCMODE", O_ACCMODE
, TARGET_O_ACCMODE
},
713 { "O_RDONLY", O_RDONLY
, TARGET_O_RDONLY
},
716 { "O_WRONLY", O_WRONLY
, TARGET_O_WRONLY
},
719 { "O_RDWR", O_RDWR
, 0x2 },
722 { "O_CREAT", O_CREAT
, 0x40 },
725 { "O_EXCL", O_EXCL
, 0x80 },
728 { "O_NOCTTY", O_NOCTTY
, 0x100 },
731 { "O_TRUNC", O_TRUNC
, 0x200 },
734 { "O_APPEND", O_APPEND
, 0x400 },
737 { "O_NONBLOCK", O_NONBLOCK
, 0x800 },
740 { "O_NDELAY", O_NDELAY
, 0x0 },
743 { "O_SYNC", O_SYNC
, 0x1000 },
746 { "FASYNC", FASYNC
, 0x2000 },
749 { "O_DIRECT", O_DIRECT
, 0x4000 },
752 { "O_LARGEFILE", O_LARGEFILE
, 0x8000 },
755 { "O_DIRECTORY", O_DIRECTORY
, 0x10000 },
758 { "O_NOFOLLOW", O_NOFOLLOW
, 0x20000 },
763 /* Let's be less drastic and more traceable. FIXME: mark as noreturn. */
765 sim_io_error (sd, "simulator unhandled condition at %s:%d", \
766 __FUNCTION__, __LINE__)
768 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
769 static SIM_CPU
*current_cpu_for_cb_callback
;
771 static USI
create_map (SIM_DESC
, struct cris_sim_mmapped_page
**,
773 static USI
unmap_pages (SIM_DESC
, struct cris_sim_mmapped_page
**,
775 static USI
is_mapped (SIM_DESC
, struct cris_sim_mmapped_page
**,
777 static void dump_statistics (SIM_CPU
*current_cpu
);
778 static void make_first_thread (SIM_CPU
*current_cpu
);
780 /* When we risk running self-modified code (as in trampolines), this is
781 called from special-case insns. The silicon CRIS CPU:s have enough
782 cache snooping implemented making this a simulator-only issue. Tests:
783 gcc.c-torture/execute/931002-1.c execution, -O3 -g
784 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
787 cris_flush_simulator_decode_cache (SIM_CPU
*current_cpu
,
788 USI pc ATTRIBUTE_UNUSED
)
790 SIM_DESC sd
= CPU_STATE (current_cpu
);
793 if (USING_SCACHE_P (sd
))
794 scache_flush_cpu (current_cpu
);
798 /* Output statistics at the end of a run. */
800 dump_statistics (SIM_CPU
*current_cpu
)
802 SIM_DESC sd
= CPU_STATE (current_cpu
);
803 CRIS_MISC_PROFILE
*profp
804 = CPU_CRIS_MISC_PROFILE (current_cpu
);
805 unsigned64 total
= profp
->basic_cycle_count
;
806 const char *textmsg
= "Basic clock cycles, total @: %llu\n";
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
:
816 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
818 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
819 total
+= profp
->unaligned_mem_dword_count
;
822 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
823 textmsg
= "Schedulable clock cycles, total @: %llu\n";
825 += (profp
->memsrc_stall_count
826 + profp
->memraw_stall_count
827 + profp
->movemsrc_stall_count
828 + profp
->movemdst_stall_count
829 + profp
->mulsrc_stall_count
830 + profp
->jumpsrc_stall_count
831 + profp
->unaligned_mem_dword_count
);
834 case FLAG_CRIS_MISC_PROFILE_ALL
:
835 textmsg
= "All accounted clock cycles, total @: %llu\n";
837 += (profp
->memsrc_stall_count
838 + profp
->memraw_stall_count
839 + profp
->movemsrc_stall_count
840 + profp
->movemdst_stall_count
841 + profp
->movemaddr_stall_count
842 + profp
->mulsrc_stall_count
843 + profp
->jumpsrc_stall_count
844 + profp
->branch_stall_count
845 + profp
->jumptarget_stall_count
846 + profp
->unaligned_mem_dword_count
);
853 "Internal inconsistency at %s:%d",
855 sim_engine_halt (sd
, current_cpu
, NULL
, 0,
856 sim_stopped
, SIM_SIGILL
);
859 /* Historically, these messages have gone to stderr, so we'll keep it
860 that way. It's also easier to then tell it from normal program
861 output. FIXME: Add redirect option like "run -e file". */
862 sim_io_eprintf (sd
, textmsg
, total
);
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: %llu\n",
867 (unsigned long long) (profp
->memsrc_stall_count
868 + profp
->unaligned_mem_dword_count
));
869 sim_io_eprintf (sd
, "Memory read-after-write stall cycles: %llu\n",
870 (unsigned long long) profp
->memraw_stall_count
);
871 sim_io_eprintf (sd
, "Movem source stall cycles: %llu\n",
872 (unsigned long long) profp
->movemsrc_stall_count
);
873 sim_io_eprintf (sd
, "Movem destination stall cycles: %llu\n",
874 (unsigned long long) profp
->movemdst_stall_count
);
875 sim_io_eprintf (sd
, "Movem address stall cycles: %llu\n",
876 (unsigned long long) profp
->movemaddr_stall_count
);
877 sim_io_eprintf (sd
, "Multiplication source stall cycles: %llu\n",
878 (unsigned long long) profp
->mulsrc_stall_count
);
879 sim_io_eprintf (sd
, "Jump source stall cycles: %llu\n",
880 (unsigned long long) profp
->jumpsrc_stall_count
);
881 sim_io_eprintf (sd
, "Branch misprediction stall cycles: %llu\n",
882 (unsigned long long) profp
->branch_stall_count
);
883 sim_io_eprintf (sd
, "Jump target stall cycles: %llu\n",
884 (unsigned long long) profp
->jumptarget_stall_count
);
887 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
888 Return 1 if a overlap detected, 0 otherwise. */
891 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED
,
892 struct cris_sim_mmapped_page
**rootp
,
895 struct cris_sim_mmapped_page
*mapp
;
897 if (len
== 0 || (len
& 8191))
900 /* Iterate over the reverse-address sorted pages until we find a page in
901 or lower than the checked area. */
902 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
903 if (mapp
->addr
< addr
+ len
&& mapp
->addr
>= addr
)
909 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
910 Return 1 if the whole area is mapped, 0 otherwise. */
913 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED
,
914 struct cris_sim_mmapped_page
**rootp
,
917 struct cris_sim_mmapped_page
*mapp
;
919 if (len
== 0 || (len
& 8191))
922 /* Iterate over the reverse-address sorted pages until we find a page
923 lower than the checked area. */
924 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
925 if (addr
== mapp
->addr
&& len
== 8192)
927 else if (addr
+ len
> mapp
->addr
)
933 /* Debug helper; to be run from gdb. */
936 cris_dump_map (SIM_CPU
*current_cpu
)
938 struct cris_sim_mmapped_page
*mapp
;
941 for (mapp
= current_cpu
->highest_mmapped_page
,
942 start
= mapp
== NULL
? 0 : mapp
->addr
+ 8192,
943 end
= mapp
== NULL
? 0 : mapp
->addr
+ 8191;
947 if (mapp
->addr
!= start
- 8192)
949 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
950 end
= mapp
->addr
+ 8191;
956 if (current_cpu
->highest_mmapped_page
!= NULL
)
957 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
960 /* Create mmapped memory. ADDR is -1 if any address will do. Caller
961 must make sure that the address isn't already mapped. */
964 create_map (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
967 struct cris_sim_mmapped_page
*mapp
;
968 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
969 USI new_addr
= 0x40000000;
971 if (addr
!= (USI
) -1)
973 else if (*rootp
&& rootp
[0]->addr
>= new_addr
)
974 new_addr
= rootp
[0]->addr
+ 8192;
981 /* Which is better: return an error for this, or just round it up? */
984 /* Do a recursive call for each page in the request. */
985 for (page_addr
= new_addr
; len
!= 0; page_addr
+= 8192, len
-= 8192)
986 if (create_map (sd
, rootp
, page_addr
, 8192) >= (USI
) -8191)
993 mapp
!= NULL
&& mapp
->addr
> new_addr
;
995 higher_prevp
= &mapp
->prev
;
997 /* Assert for consistency that we don't create duplicate maps. */
998 if (is_mapped (sd
, rootp
, new_addr
, len
))
1001 /* Allocate the new page, on the next higher page from the last one
1002 allocated, and link in the new descriptor before previous ones. */
1003 mapp
= malloc (sizeof (*mapp
));
1006 return (USI
) -ENOMEM
;
1008 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1012 mapp
->addr
= new_addr
;
1013 mapp
->prev
= *higher_prevp
;
1014 *higher_prevp
= mapp
;
1019 /* Unmap one or more pages. */
1022 unmap_pages (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
1025 struct cris_sim_mmapped_page
*mapp
;
1026 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
1034 /* Which is better: return an error for this, or just round it up? */
1037 /* Loop backwards to make each call is O(1) over the number of pages
1038 allocated, if we're unmapping from the high end of the pages. */
1039 for (page_addr
= addr
+ len
- 8192;
1042 if (unmap_pages (sd
, rootp
, page_addr
, 8192))
1045 if (unmap_pages (sd
, rootp
, addr
, 8192))
1051 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
> addr
; mapp
= mapp
->prev
)
1052 higher_prevp
= &mapp
->prev
;
1054 if (mapp
== NULL
|| mapp
->addr
!= addr
)
1057 *higher_prevp
= mapp
->prev
;
1058 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1063 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1066 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC vpc
)
1068 SIM_DESC sd
= CPU_STATE (current_cpu
);
1070 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
1074 /* Handlers from the CGEN description that should not be called. */
1077 cris_bmod_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1078 UINT srcreg ATTRIBUTE_UNUSED
,
1079 USI dstreg ATTRIBUTE_UNUSED
)
1081 SIM_DESC sd
= CPU_STATE (current_cpu
);
1086 h_supr_set_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1087 UINT index ATTRIBUTE_UNUSED
,
1088 USI page ATTRIBUTE_UNUSED
,
1089 USI newval ATTRIBUTE_UNUSED
)
1091 SIM_DESC sd
= CPU_STATE (current_cpu
);
1096 h_supr_get_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1097 UINT index ATTRIBUTE_UNUSED
,
1098 USI page ATTRIBUTE_UNUSED
)
1100 SIM_DESC sd
= CPU_STATE (current_cpu
);
1104 /* Swap one context for another. */
1107 schedule (SIM_CPU
*current_cpu
, int next
)
1109 /* Need to mark context-switches in the trace output. */
1110 if ((CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1111 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE
))
1112 cris_trace_printf (CPU_STATE (current_cpu
), current_cpu
,
1115 /* Copy the current context (if there is one) to its slot. */
1116 if (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
)
1117 memcpy (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
,
1118 ¤t_cpu
->cpu_data_placeholder
,
1119 current_cpu
->thread_cpu_data_size
);
1121 /* Copy the new context from its slot. */
1122 memcpy (¤t_cpu
->cpu_data_placeholder
,
1123 current_cpu
->thread_data
[next
].cpu_context
,
1124 current_cpu
->thread_cpu_data_size
);
1126 /* Update needed stuff to indicate the new context. */
1127 current_cpu
->threadno
= next
;
1129 /* Handle pending signals. */
1130 if (current_cpu
->thread_data
[next
].sigpending
1131 /* We don't run nested signal handlers. This means that pause(2)
1132 and sigsuspend(2) do not work in sighandlers, but that
1133 shouldn't be too hard a restriction. It also greatly
1134 simplifies the code. */
1135 && current_cpu
->thread_data
[next
].cpu_context_atsignal
== NULL
)
1139 /* See if there's really a pending, non-blocked handler. We don't
1140 queue signals, so just use the first one in ascending order. */
1141 for (sig
= 0; sig
< 64; sig
++)
1142 if (current_cpu
->thread_data
[next
].sigdata
[sig
].pending
1143 && !current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
)
1149 USI pc
= sim_pc_get (current_cpu
);
1151 /* It's simpler to save the CPU context inside the simulator
1152 than on the stack. */
1153 current_cpu
->thread_data
[next
].cpu_context_atsignal
1155 ->make_thread_cpu_data
) (current_cpu
,
1156 current_cpu
->thread_data
[next
]
1159 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1160 sp
= bfd_getl32 (regbuf
);
1162 /* Make sure we have an aligned stack. */
1165 /* Make room for the signal frame, aligned. FIXME: Check that
1166 the memory exists, map it in if absent. (BTW, should also
1167 implement on-access automatic stack allocation). */
1170 /* This isn't the same signal frame as the kernel uses, because
1171 we don't want to bother getting all registers on and off the
1174 /* First, we store the currently blocked signals. */
1176 for (i
= 0; i
< 32; i
++)
1178 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 1].blocked
<< i
;
1179 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
, blocked
);
1181 for (i
= 0; i
< 31; i
++)
1183 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 33].blocked
<< i
;
1184 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
+ 4, blocked
);
1186 /* Then, the actual instructions. This is CPU-specific, but we
1187 use instructions from the common subset for v10 and v32 which
1188 should be safe for the time being but could be parametrized
1190 /* MOVU.W [PC+],R9. */
1191 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 8, 0x9c5f);
1192 /* .WORD TARGET_SYS_sigreturn. */
1193 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 10,
1194 TARGET_SYS_sigreturn
);
1196 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 12, 0xe93d);
1198 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1199 instruction. Still, it doesn't matter because v10 has no
1200 delay slot for BREAK so it will not be executed). */
1201 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 16, 0x05b0);
1203 /* Modify registers to hold the right values for the sighandler
1204 context: updated stackpointer and return address pointing to
1205 the sigreturn stub. */
1206 bfd_putl32 (sp
, regbuf
);
1207 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1208 bfd_putl32 (sp
+ 8, regbuf
);
1209 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, TARGET_SRP_REGNUM
,
1212 current_cpu
->thread_data
[next
].sigdata
[sig
].pending
= 0;
1214 /* Block this signal (for the duration of the sighandler). */
1215 current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
= 1;
1217 sim_pc_set (current_cpu
, current_cpu
->sighandler
[sig
]);
1218 bfd_putl32 (sig
, regbuf
);
1219 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
,
1222 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1223 needed all this for, specifies a SA_SIGINFO call but treats it
1224 like an ordinary sighandler; only the signal number argument is
1225 inspected. To make future need to implement SA_SIGINFO
1226 correctly possible, we set the siginfo argument register to a
1227 magic (hopefully non-address) number. (NB: then, you should
1228 just need to pass the siginfo argument; it seems you probably
1229 don't need to implement the specific rt_sigreturn.) */
1230 bfd_putl32 (0xbad5161f, regbuf
);
1231 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R11
,
1234 /* The third argument is unused and the kernel sets it to 0. */
1235 bfd_putl32 (0, regbuf
);
1236 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R12
,
1241 /* No, there actually was no pending signal for this thread. Reset
1243 current_cpu
->thread_data
[next
].sigpending
= 0;
1247 /* Reschedule the simplest possible way until something else is absolutely
1249 - A. Find the next process (round-robin) that doesn't have at_syscall
1251 - B. If there is none, just run the next process, round-robin.
1252 - Clear at_syscall for the current process. */
1255 reschedule (SIM_CPU
*current_cpu
)
1257 SIM_DESC sd
= CPU_STATE (current_cpu
);
1260 /* Iterate over all thread slots, because after a few thread creations
1261 and exits, we don't know where the live ones are. */
1262 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1263 i
!= current_cpu
->threadno
;
1264 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1265 if (current_cpu
->thread_data
[i
].cpu_context
1266 && current_cpu
->thread_data
[i
].at_syscall
== 0)
1268 schedule (current_cpu
, i
);
1272 /* Pick any next live thread. */
1273 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1274 i
!= current_cpu
->threadno
;
1275 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1276 if (current_cpu
->thread_data
[i
].cpu_context
)
1278 schedule (current_cpu
, i
);
1282 /* More than one live thread, but we couldn't find the next one? */
1286 /* Set up everything to receive (or IGN) an incoming signal to the
1290 deliver_signal (SIM_CPU
*current_cpu
, int sig
, unsigned int pid
)
1293 USI pc
= sim_pc_get (current_cpu
);
1295 /* Find the thread index of the pid. */
1296 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
1297 /* Apparently it's ok to send signals to zombies (so a check for
1298 current_cpu->thread_data[i].cpu_context != NULL would be
1300 if (current_cpu
->thread_data
[i
].threadid
== pid
- TARGET_PID
)
1303 switch (current_cpu
->sighandler
[sig
])
1305 case TARGET_SIG_DFL
:
1308 /* The following according to the glibc
1309 documentation. (The kernel code has non-obvious
1310 execution paths.) */
1313 case TARGET_SIGSEGV
:
1315 case TARGET_SIGABRT
:
1316 case TARGET_SIGTRAP
:
1319 case TARGET_SIGTERM
:
1321 case TARGET_SIGQUIT
:
1322 case TARGET_SIGKILL
:
1325 case TARGET_SIGALRM
:
1326 case TARGET_SIGVTALRM
:
1327 case TARGET_SIGPROF
:
1328 case TARGET_SIGSTOP
:
1330 case TARGET_SIGPIPE
:
1331 case TARGET_SIGLOST
:
1332 case TARGET_SIGXCPU
:
1333 case TARGET_SIGXFSZ
:
1334 case TARGET_SIGUSR1
:
1335 case TARGET_SIGUSR2
:
1336 sim_io_eprintf (CPU_STATE (current_cpu
),
1337 "Exiting pid %d due to signal %d\n",
1339 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1340 NULL
, pc
, sim_stopped
,
1341 sig
== TARGET_SIGABRT
1342 ? SIM_SIGABRT
: SIM_SIGILL
);
1345 /* The default for all other signals is to be ignored. */
1350 case TARGET_SIG_IGN
:
1353 case TARGET_SIGKILL
:
1354 case TARGET_SIGSTOP
:
1355 /* Can't ignore these signals. */
1356 sim_io_eprintf (CPU_STATE (current_cpu
),
1357 "Exiting pid %d due to signal %d\n",
1359 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1360 NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1369 /* Mark the signal as pending, making schedule () check
1370 closer. The signal will be handled when the thread is
1371 scheduled and the signal is unblocked. */
1372 current_cpu
->thread_data
[i
].sigdata
[sig
].pending
= 1;
1373 current_cpu
->thread_data
[i
].sigpending
= 1;
1378 sim_io_eprintf (CPU_STATE (current_cpu
),
1379 "Unimplemented signal: %d\n", sig
);
1380 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
1381 sim_stopped
, SIM_SIGILL
);
1386 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu
)),
1390 /* Make the vector and the first item, the main thread. */
1393 make_first_thread (SIM_CPU
*current_cpu
)
1395 SIM_DESC sd
= CPU_STATE (current_cpu
);
1396 current_cpu
->thread_data
1398 SIM_TARGET_MAX_THREADS
1399 * sizeof (current_cpu
->thread_data
[0]));
1400 current_cpu
->thread_data
[0].cpu_context
1401 = (*current_cpu
->make_thread_cpu_data
) (current_cpu
,
1403 ->cpu_data_placeholder
);
1404 current_cpu
->thread_data
[0].parent_threadid
= -1;
1406 /* For good measure. */
1407 if (TARGET_SIG_DFL
!= 0)
1411 /* Handle unknown system calls. Returns (if it does) the syscall
1415 cris_unknown_syscall (SIM_CPU
*current_cpu
, USI pc
, char *s
, ...)
1417 SIM_DESC sd
= CPU_STATE (current_cpu
);
1418 host_callback
*cb
= STATE_CALLBACK (sd
);
1420 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
1421 || cris_unknown_syscall_action
== CRIS_USYSC_MSG_ENOSYS
)
1426 sim_io_evprintf (sd
, s
, ap
);
1429 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
)
1430 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1433 return -cb_host_to_target_errno (cb
, ENOSYS
);
1436 /* Main function: the handler of the "break 13" syscall insn. */
1439 cris_break_13_handler (SIM_CPU
*current_cpu
, USI callnum
, USI arg1
,
1440 USI arg2
, USI arg3
, USI arg4
, USI arg5
, USI arg6
,
1444 SIM_DESC sd
= CPU_STATE (current_cpu
);
1445 host_callback
*cb
= STATE_CALLBACK (sd
);
1447 int threadno
= current_cpu
->threadno
;
1449 current_cpu
->syscalls
++;
1451 CB_SYSCALL_INIT (&s
);
1457 /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need
1458 to sign-extend the lseek offset to be passed as a signed number,
1459 else we'll truncate it to something > 2GB on hosts where sizeof
1460 long > sizeof USI. We avoid doing it for all syscalls, as arg2 is
1461 e.g. an address for some syscalls. */
1462 if (callnum
== TARGET_SYS_lseek
)
1465 if (callnum
== TARGET_SYS_exit_group
1466 || (callnum
== TARGET_SYS_exit
&& current_cpu
->m1threads
== 0))
1468 if (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1469 & FLAG_CRIS_MISC_PROFILE_ALL
)
1470 dump_statistics (current_cpu
);
1471 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
1475 s
.p2
= (PTR
) current_cpu
;
1476 s
.read_mem
= sim_syscall_read_mem
;
1477 s
.write_mem
= sim_syscall_write_mem
;
1479 current_cpu_for_cb_callback
= current_cpu
;
1481 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1484 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
1486 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1489 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
1491 if (s
.errcode
!= 0 && s
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
1493 /* If the generic simulator call said ENOSYS, then let's try the
1494 ones we know ourselves.
1496 The convention is to provide *very limited* functionality on an
1497 as-needed basis, only what's covered by the test-suite, tests
1498 added when functionality changes and abort with a descriptive
1499 message for *everything* else. Where there's no test-case, we
1504 /* It's a pretty safe bet that the "old setup() system call"
1505 number will not be re-used; we can't say the same for higher
1506 numbers. We treat this simulator-generated call as "wait
1507 forever"; we re-run this insn. The wait is ended by a
1508 callback. Sanity check that this is the reason we got
1510 if (current_cpu
->thread_data
== NULL
1511 || (current_cpu
->thread_data
[threadno
].pipe_write_fd
== 0))
1512 goto unimplemented_syscall
;
1514 sim_pc_set (current_cpu
, pc
);
1518 case TARGET_SYS_fcntl64
:
1519 case TARGET_SYS_fcntl
:
1524 Glibc checks stdin, stdout and stderr fd:s for
1525 close-on-exec security sanity. We just need to provide a
1526 OK return value. If we really need to have a
1527 close-on-exec flag true, we could just do a real fcntl
1533 /* F_SETFD. Just ignore attempts to set the close-on-exec
1539 /* F_GETFL. Check for the special case for open+fdopen. */
1540 if (current_cpu
->last_syscall
== TARGET_SYS_open
1541 && arg1
== current_cpu
->last_open_fd
)
1543 retval
= current_cpu
->last_open_flags
& TARGET_O_ACCMODE
;
1548 /* Because we can't freopen fd:s 0, 1, 2 to mean
1549 something else than stdin, stdout and stderr
1550 (sim/common/syscall.c:cb_syscall special cases fd
1551 0, 1 and 2), we know what flags that we can
1552 sanely return for these fd:s. */
1553 retval
= TARGET_O_RDONLY
;
1556 else if (arg1
== 1 || arg1
== 2)
1558 retval
= TARGET_O_WRONLY
;
1563 /* Nothing else is implemented. */
1565 = cris_unknown_syscall (current_cpu
, pc
,
1566 "Unimplemented %s syscall "
1567 "(fd: 0x%lx: cmd: 0x%lx arg: "
1569 callnum
== TARGET_SYS_fcntl
1570 ? "fcntl" : "fcntl64",
1571 (unsigned long) (USI
) arg1
,
1572 (unsigned long) (USI
) arg2
,
1573 (unsigned long) (USI
) arg3
);
1578 case TARGET_SYS_uname
:
1580 /* Fill in a few constants to appease glibc. */
1581 static char sim_utsname
[6][65] =
1587 "cris", /* Overwritten below. */
1591 /* Having the hardware type in Linux equal to the bfd
1592 printable name is deliberate: if you make config.guess
1593 work on your Linux-type system the usual way, it
1594 probably will; either the bfd printable_name or the
1595 ambiguous arch_name. */
1596 strcpy (sim_utsname
[4], STATE_ARCHITECTURE (sd
)->printable_name
);
1598 if ((s
.write_mem
) (cb
, &s
, arg1
, (const char *) sim_utsname
,
1599 sizeof (sim_utsname
))
1600 != sizeof (sim_utsname
))
1601 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
1607 case TARGET_SYS_geteuid32
:
1608 /* We tell the truth with these. Maybe we shouldn't, but it
1609 should match the "stat" information. */
1610 retval
= geteuid ();
1613 case TARGET_SYS_getuid32
:
1617 case TARGET_SYS_getegid32
:
1618 retval
= getegid ();
1621 case TARGET_SYS_getgid32
:
1625 case TARGET_SYS_brk
:
1626 /* Most often, we just return the argument, like the Linux
1631 retval
= current_cpu
->endbrk
;
1632 else if (arg1
<= current_cpu
->endmem
)
1633 current_cpu
->endbrk
= arg1
;
1636 USI new_end
= (arg1
+ 8191) & ~8191;
1638 /* If the simulator wants to brk more than a certain very
1639 large amount, something is wrong. FIXME: Return an error
1640 or abort? Have command-line selectable? */
1641 if (new_end
- current_cpu
->endmem
> SIM_MAX_ALLOC_CHUNK
)
1643 current_cpu
->endbrk
= current_cpu
->endmem
;
1644 retval
= current_cpu
->endmem
;
1648 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1649 current_cpu
->endmem
,
1650 new_end
- current_cpu
->endmem
,
1652 current_cpu
->endbrk
= arg1
;
1653 current_cpu
->endmem
= new_end
;
1657 case TARGET_SYS_getpid
:
1658 /* Correct until CLONE_THREAD is implemented. */
1659 retval
= current_cpu
->thread_data
== NULL
1661 : TARGET_PID
+ current_cpu
->thread_data
[threadno
].threadid
;
1664 case TARGET_SYS_getppid
:
1665 /* Correct until CLONE_THREAD is implemented. */
1666 retval
= current_cpu
->thread_data
== NULL
1669 + current_cpu
->thread_data
[threadno
].parent_threadid
);
1672 case TARGET_SYS_mmap2
:
1681 /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1682 still masked away this bit, so let's just ignore
1684 flags
&= ~TARGET_MAP_DENYWRITE
;
1686 /* If the simulator wants to mmap more than the very large
1687 limit, something is wrong. FIXME: Return an error or
1688 abort? Have command-line selectable? */
1689 if (len
> SIM_MAX_ALLOC_CHUNK
)
1691 retval
= -cb_host_to_target_errno (cb
, ENOMEM
);
1695 if ((prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
)
1697 != (TARGET_PROT_READ
1699 | TARGET_PROT_EXEC
))
1700 && (prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
))
1701 && prot
!= TARGET_PROT_READ
)
1702 || (flags
!= (TARGET_MAP_ANONYMOUS
| TARGET_MAP_PRIVATE
)
1703 && flags
!= TARGET_MAP_PRIVATE
1704 && flags
!= (TARGET_MAP_ANONYMOUS
1705 | TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1706 && flags
!= (TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1707 && flags
!= TARGET_MAP_SHARED
)
1709 && prot
!= TARGET_PROT_READ
1710 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1711 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1712 || (fd
== (USI
) -1 && pgoff
!= 0)
1713 || (fd
!= (USI
) -1 && (flags
& TARGET_MAP_ANONYMOUS
)))
1716 = cris_unknown_syscall (current_cpu
, pc
,
1717 "Unimplemented mmap2 call "
1718 "(0x%lx, 0x%lx, 0x%lx, "
1719 "0x%lx, 0x%lx, 0x%lx)\n",
1720 (unsigned long) arg1
,
1721 (unsigned long) arg2
,
1722 (unsigned long) arg3
,
1723 (unsigned long) arg4
,
1724 (unsigned long) arg5
,
1725 (unsigned long) arg6
);
1728 else if (fd
!= (USI
) -1)
1735 /* A non-aligned argument is allowed for files. */
1736 USI newlen
= (len
+ 8191) & ~8191;
1738 /* We only support read, read|exec, and read|write,
1739 which we should already have checked. Check again
1741 if (prot
!= TARGET_PROT_READ
1742 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1743 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1746 if (flags
& TARGET_MAP_FIXED
)
1747 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1749 else if (is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1754 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1755 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1759 if (newaddr
>= (USI
) -8191)
1762 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1766 /* We were asked for MAP_FIXED, but couldn't. */
1767 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1770 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1772 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1776 /* Find the current position in the file. */
1777 s
.func
= TARGET_SYS_lseek
;
1781 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1788 /* Move to the correct offset in the file. */
1789 s
.func
= TARGET_SYS_lseek
;
1791 s
.arg2
= pgoff
*8192;
1793 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1799 /* Use the standard read callback to read in "len"
1801 s
.func
= TARGET_SYS_read
;
1805 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1808 /* If the result is a page or more lesser than what
1809 was requested, something went wrong. */
1810 if (len
>= 8192 && (USI
) s
.result
<= len
- 8192)
1813 /* After reading, we need to go back to the previous
1814 position in the file. */
1815 s
.func
= TARGET_SYS_lseek
;
1819 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1821 if (pos
!= (USI
) s
.result
)
1828 USI newlen
= (len
+ 8191) & ~8191;
1831 if (flags
& TARGET_MAP_FIXED
)
1832 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1834 else if (is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1838 newaddr
= create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1839 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1843 if (newaddr
>= (USI
) -8191)
1844 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1848 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1851 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1853 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1860 case TARGET_SYS_mprotect
:
1862 /* We only cover the case of linuxthreads mprotecting out
1863 its stack guard page and of dynamic loading mprotecting
1864 away the data (for some reason the whole library, then
1865 mprotects away the data part and mmap-FIX:es it again. */
1870 if (prot
!= TARGET_PROT_NONE
1871 || !is_mapped_only (sd
, ¤t_cpu
->highest_mmapped_page
,
1872 addr
, (len
+ 8191) & ~8191))
1875 = cris_unknown_syscall (current_cpu
, pc
,
1876 "Unimplemented mprotect call "
1877 "(0x%lx, 0x%lx, 0x%lx)\n",
1878 (unsigned long) arg1
,
1879 (unsigned long) arg2
,
1880 (unsigned long) arg3
);
1884 /* Just ignore this. We could make this equal to munmap,
1885 but then we'd have to make sure no anon mmaps gets this
1886 address before a subsequent MAP_FIXED mmap intended to
1892 case TARGET_SYS_ioctl
:
1894 /* We support only a very limited functionality: checking
1895 stdout with TCGETS to perform the isatty function. The
1896 TCGETS ioctl isn't actually performed or the result used by
1897 an isatty () caller in a "hello, world" program; only the
1898 return value is then used. Maybe we shouldn't care about
1899 the environment of the simulator regarding isatty, but
1900 that's been working before, in the xsim simulator. */
1901 if (arg2
== TARGET_TCGETS
&& arg1
== 1)
1902 retval
= isatty (1) ? 0 : cb_host_to_target_errno (cb
, EINVAL
);
1904 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1908 case TARGET_SYS_munmap
:
1913 = unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1915 retval
= result
!= 0 ? -cb_host_to_target_errno (cb
, result
) : 0;
1919 case TARGET_SYS_wait4
:
1927 /* FIXME: We're not properly implementing __WCLONE, and we
1928 don't really need the special casing so we might as well
1929 make this general. */
1930 if ((!(pid
== (USI
) -1
1931 && options
== (TARGET___WCLONE
| TARGET_WNOHANG
)
1934 && (options
== TARGET___WCLONE
1935 || options
== TARGET___WALL
)))
1937 || current_cpu
->thread_data
== NULL
)
1940 = cris_unknown_syscall (current_cpu
, pc
,
1941 "Unimplemented wait4 call "
1942 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1943 (unsigned long) arg1
,
1944 (unsigned long) arg2
,
1945 (unsigned long) arg3
,
1946 (unsigned long) arg4
);
1950 if (pid
== (USI
) -1)
1951 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1953 if (current_cpu
->thread_data
[threadno
].threadid
1954 == current_cpu
->thread_data
[i
].parent_threadid
1955 && current_cpu
->thread_data
[i
].threadid
!= 0
1956 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1958 /* A zombied child. Get the exit value and clear the
1959 zombied entry so it will be reused. */
1960 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, saddr
,
1962 ->thread_data
[i
].exitval
);
1964 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1965 memset (¤t_cpu
->thread_data
[i
], 0,
1966 sizeof (current_cpu
->thread_data
[i
]));
1972 /* We're waiting for a specific PID. If we don't find
1973 it zombied on this run, rerun the syscall. */
1974 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1975 if (pid
== current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
1976 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1979 /* Get the exit value if the caller wants it. */
1980 sim_core_write_unaligned_4 (current_cpu
, pc
, 0,
1987 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1988 memset (¤t_cpu
->thread_data
[i
], 0,
1989 sizeof (current_cpu
->thread_data
[i
]));
1994 sim_pc_set (current_cpu
, pc
);
1997 retval
= -cb_host_to_target_errno (cb
, ECHILD
);
2002 case TARGET_SYS_rt_sigaction
:
2010 __sighandler_t sa_handler;
2011 unsigned long sa_flags;
2012 void (*sa_restorer)(void);
2018 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, old_sa
+ 0,
2019 current_cpu
->sighandler
[signum
]);
2020 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 4, 0);
2021 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 8, 0);
2023 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
2024 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 12, 0);
2025 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 16, 0);
2029 USI target_sa_handler
2030 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
);
2032 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 4);
2033 USI target_sa_restorer
2034 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 8);
2035 USI target_sa_mask_low
2036 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 12);
2037 USI target_sa_mask_high
2038 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 16);
2040 /* We won't interrupt a syscall so we won't restart it,
2041 but a signal(2) call ends up syscalling rt_sigaction
2042 with this flag, so we have to handle it. The
2043 sa_restorer field contains garbage when not
2044 TARGET_SA_RESTORER, so don't look at it. For the
2045 time being, we don't nest sighandlers, so we
2046 ignore the sa_mask, which simplifies things. */
2047 if ((target_sa_flags
!= 0
2048 && target_sa_flags
!= TARGET_SA_RESTART
2049 && target_sa_flags
!= (TARGET_SA_RESTART
|TARGET_SA_SIGINFO
))
2050 || target_sa_handler
== 0)
2053 = cris_unknown_syscall (current_cpu
, pc
,
2054 "Unimplemented rt_sigaction "
2057 "[0x%x, 0x%x, 0x%x, "
2058 "{0x%x, 0x%x}], 0x%lx)\n",
2059 (unsigned long) arg1
,
2060 (unsigned long) arg2
,
2065 target_sa_mask_high
,
2066 (unsigned long) arg3
);
2070 current_cpu
->sighandler
[signum
] = target_sa_handler
;
2072 /* Because we may have unblocked signals, one may now be
2073 pending, if there are threads, that is. */
2074 if (current_cpu
->thread_data
)
2075 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2081 case TARGET_SYS_mremap
:
2087 USI new_addr
= arg5
;
2090 if (new_len
== old_len
)
2091 /* The program and/or library is possibly confused but
2092 this is a valid call. Happens with ipps-1.40 on file
2095 else if (new_len
< old_len
)
2097 /* Shrinking is easy. */
2098 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2099 addr
+ new_len
, old_len
- new_len
) != 0)
2100 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2104 else if (! is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
2105 addr
+ old_len
, new_len
- old_len
))
2107 /* If the extension isn't mapped, we can just add it. */
2109 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2110 addr
+ old_len
, new_len
- old_len
);
2112 if (mapped_addr
> (USI
) -8192)
2113 retval
= -cb_host_to_target_errno (cb
, -(SI
) mapped_addr
);
2117 else if (flags
& TARGET_MREMAP_MAYMOVE
)
2119 /* Create a whole new map and copy the contents
2120 block-by-block there. We ignore the new_addr argument
2123 USI prev_addr
= addr
;
2124 USI prev_len
= old_len
;
2127 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2130 if (mapped_addr
> (USI
) -8192)
2132 retval
= -cb_host_to_target_errno (cb
, -(SI
) new_addr
);
2136 retval
= mapped_addr
;
2139 old_len
-= 8192, mapped_addr
+= 8192, addr
+= 8192)
2141 if (sim_core_read_buffer (sd
, current_cpu
, read_map
, buf
,
2143 || sim_core_write_buffer (sd
, current_cpu
, 0, buf
,
2144 mapped_addr
, 8192) != 8192)
2148 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2149 prev_addr
, prev_len
) != 0)
2153 retval
= -cb_host_to_target_errno (cb
, -ENOMEM
);
2157 case TARGET_SYS_poll
:
2159 int npollfds
= arg2
;
2175 /* Check that this is the expected poll call from
2176 linuxthreads/manager.c; we don't support anything else.
2177 Remember, fd == 0 isn't supported. */
2179 || ((fd
= sim_core_read_unaligned_4 (current_cpu
, pc
,
2181 || ((events
= sim_core_read_unaligned_2 (current_cpu
, pc
,
2184 || ((cb
->to_fstat
) (cb
, fd
, &buf
) != 0
2185 || (buf
.st_mode
& S_IFIFO
) == 0)
2186 || current_cpu
->thread_data
== NULL
)
2189 = cris_unknown_syscall (current_cpu
, pc
,
2190 "Unimplemented poll syscall "
2191 "(0x%lx: [0x%x, 0x%x, x], "
2193 (unsigned long) arg1
, fd
, events
,
2194 (unsigned long) arg2
,
2195 (unsigned long) arg3
);
2201 /* Iterate over threads; find a marker that a writer is
2202 sleeping, waiting for a reader. */
2203 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2204 if (current_cpu
->thread_data
[i
].cpu_context
!= NULL
2205 && current_cpu
->thread_data
[i
].pipe_read_fd
== fd
)
2207 revents
= TARGET_POLLIN
;
2212 /* Timeout decreases with whatever time passed between the
2213 last syscall and this. That's not exactly right for the
2214 first call, but it's close enough that it isn't
2215 worthwhile to complicate matters by making that a special
2218 -= (TARGET_TIME_MS (current_cpu
)
2219 - (current_cpu
->thread_data
[threadno
].last_execution
));
2221 /* Arrange to repeat this syscall until timeout or event,
2222 decreasing timeout at each iteration. */
2223 if (timeout
> 0 && revents
== 0)
2225 bfd_byte timeout_buf
[4];
2227 bfd_putl32 (timeout
, timeout_buf
);
2228 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2229 H_GR_R12
, timeout_buf
, 4);
2230 sim_pc_set (current_cpu
, pc
);
2235 sim_core_write_unaligned_2 (current_cpu
, pc
, 0, ufds
+ 4 + 2,
2240 case TARGET_SYS_time
:
2242 retval
= (int) (*cb
->time
) (cb
);
2244 /* At time of this writing, CB_SYSCALL_time doesn't do the
2245 part of setting *arg1 to the return value. */
2247 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, retval
);
2251 case TARGET_SYS_gettimeofday
:
2254 USI ts
= TARGET_TIME (current_cpu
);
2255 USI tms
= TARGET_TIME_MS (current_cpu
);
2257 /* First dword is seconds since TARGET_EPOCH. */
2258 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, ts
);
2260 /* Second dword is microseconds. */
2261 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4,
2262 (tms
% 1000) * 1000);
2266 /* Time-zone info is always cleared. */
2267 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, 0);
2268 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, 0);
2273 case TARGET_SYS_llseek
:
2275 /* If it fits, tweak parameters to fit the "generic" 32-bit
2276 lseek and use that. */
2284 if (!((offs_hi
== 0 && offs_lo
>= 0)
2285 || (offs_hi
== -1 && offs_lo
< 0)))
2288 = cris_unknown_syscall (current_cpu
, pc
,
2289 "Unimplemented llseek offset,"
2290 " fd %d: 0x%x:0x%x\n",
2291 fd
, (unsigned) arg2
,
2296 s
.func
= TARGET_SYS_lseek
;
2299 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2301 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
2303 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2306 retval
= -s
.errcode
;
2309 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
,
2311 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
+ 4,
2312 s
.result
< 0 ? -1 : 0);
2317 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2320 void *iov_base; Starting address
2321 size_t iov_len; Number of bytes to transfer
2323 case TARGET_SYS_writev
:
2331 /* We'll ignore strict error-handling and just do multiple write calls. */
2332 for (i
= 0; i
< iovcnt
; i
++)
2336 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2339 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2342 s
.func
= TARGET_SYS_write
;
2347 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2349 sysret
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2351 if (sysret
!= iov_len
)
2366 /* This one does have a generic callback function, but at the time
2367 of this writing, cb_syscall does not have code for it, and we
2368 need target-specific code for the threads implementation
2370 case TARGET_SYS_kill
:
2377 /* At kill(2), glibc sets signal masks such that the thread
2378 machinery is initialized. Still, there is and was only
2380 if (current_cpu
->max_threadid
== 0)
2382 if (pid
!= TARGET_PID
)
2384 retval
= -cb_host_to_target_errno (cb
, EPERM
);
2388 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2389 if (sig
== TARGET_SIGABRT
)
2390 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2391 the end-point for failing GCC test-cases. */
2392 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2396 sim_io_eprintf (sd
, "Unimplemented signal: %d\n", sig
);
2397 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2401 /* This will not be reached. */
2405 retval
= deliver_signal (current_cpu
, sig
, pid
);
2409 case TARGET_SYS_rt_sigprocmask
:
2416 if (how
!= TARGET_SIG_BLOCK
2417 && how
!= TARGET_SIG_SETMASK
2418 && how
!= TARGET_SIG_UNBLOCK
)
2421 = cris_unknown_syscall (current_cpu
, pc
,
2422 "Unimplemented rt_sigprocmask "
2423 "syscall (0x%x, 0x%x, 0x%x)\n",
2431 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2434 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2437 /* The sigmask is kept in the per-thread data, so we may
2438 need to create the first one. */
2439 if (current_cpu
->thread_data
== NULL
)
2440 make_first_thread (current_cpu
);
2442 if (how
== TARGET_SIG_SETMASK
)
2443 for (i
= 0; i
< 64; i
++)
2444 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
= 0;
2446 for (i
= 0; i
< 32; i
++)
2447 if ((set_low
& (1 << i
)))
2448 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2449 = (how
!= TARGET_SIG_UNBLOCK
);
2451 for (i
= 0; i
< 31; i
++)
2452 if ((set_high
& (1 << i
)))
2453 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2454 = (how
!= TARGET_SIG_UNBLOCK
);
2456 /* The mask changed, so a signal may be unblocked for
2458 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2466 for (i
= 0; i
< 32; i
++)
2467 if (current_cpu
->thread_data
[threadno
]
2468 .sigdata
[i
+ 1].blocked
)
2470 for (i
= 0; i
< 31; i
++)
2471 if (current_cpu
->thread_data
[threadno
]
2472 .sigdata
[i
+ 33].blocked
)
2475 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 0, set_low
);
2476 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 4, set_high
);
2483 case TARGET_SYS_sigreturn
:
2487 int was_sigsuspended
;
2489 if (current_cpu
->thread_data
== NULL
2490 /* The CPU context is saved with the simulator data, not
2491 on the stack as in the real world. */
2492 || (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
2496 = cris_unknown_syscall (current_cpu
, pc
,
2497 "Invalid sigreturn syscall: "
2498 "no signal handler active "
2499 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2501 (unsigned long) arg1
,
2502 (unsigned long) arg2
,
2503 (unsigned long) arg3
,
2504 (unsigned long) arg4
,
2505 (unsigned long) arg5
,
2506 (unsigned long) arg6
);
2511 = current_cpu
->thread_data
[threadno
].sigsuspended
;
2513 /* Restore the sigmask, either from the stack copy made when
2514 the sighandler was called, or from the saved state
2515 specifically for sigsuspend(2). */
2516 if (was_sigsuspended
)
2518 current_cpu
->thread_data
[threadno
].sigsuspended
= 0;
2519 for (i
= 0; i
< 64; i
++)
2520 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
2521 = current_cpu
->thread_data
[threadno
]
2522 .sigdata
[i
].blocked_suspendsave
;
2530 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2531 H_GR_SP
, regbuf
, 4);
2532 sp
= bfd_getl32 (regbuf
);
2534 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
);
2536 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
+ 4);
2538 for (i
= 0; i
< 32; i
++)
2539 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2540 = (set_low
& (1 << i
)) != 0;
2541 for (i
= 0; i
< 31; i
++)
2542 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2543 = (set_high
& (1 << i
)) != 0;
2546 /* The mask changed, so a signal may be unblocked for
2548 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2550 memcpy (¤t_cpu
->cpu_data_placeholder
,
2551 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
,
2552 current_cpu
->thread_cpu_data_size
);
2553 free (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
);
2554 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
= NULL
;
2556 /* The return value must come from the saved R10. */
2557 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, regbuf
, 4);
2558 retval
= bfd_getl32 (regbuf
);
2560 /* We must also break the "sigsuspension loop". */
2561 if (was_sigsuspended
)
2562 sim_pc_set (current_cpu
, sim_pc_get (current_cpu
) + 2);
2566 case TARGET_SYS_rt_sigsuspend
:
2574 = cris_unknown_syscall (current_cpu
, pc
,
2575 "Unimplemented rt_sigsuspend syscall"
2576 " arguments (0x%lx, 0x%lx)\n",
2577 (unsigned long) arg1
,
2578 (unsigned long) arg2
);
2582 /* Don't change the signal mask if we're already in
2583 sigsuspend state (i.e. this syscall is a rerun). */
2584 else if (!current_cpu
->thread_data
[threadno
].sigsuspended
)
2587 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2590 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2594 /* Save the current sigmask and insert the user-supplied
2596 for (i
= 0; i
< 32; i
++)
2598 current_cpu
->thread_data
[threadno
]
2599 .sigdata
[i
+ 1].blocked_suspendsave
2600 = current_cpu
->thread_data
[threadno
]
2601 .sigdata
[i
+ 1].blocked
;
2603 current_cpu
->thread_data
[threadno
]
2604 .sigdata
[i
+ 1].blocked
= (set_low
& (1 << i
)) != 0;
2606 for (i
= 0; i
< 31; i
++)
2608 current_cpu
->thread_data
[threadno
]
2609 .sigdata
[i
+ 33].blocked_suspendsave
2610 = current_cpu
->thread_data
[threadno
]
2611 .sigdata
[i
+ 33].blocked
;
2612 current_cpu
->thread_data
[threadno
]
2613 .sigdata
[i
+ 33].blocked
= (set_high
& (1 << i
)) != 0;
2616 current_cpu
->thread_data
[threadno
].sigsuspended
= 1;
2618 /* The mask changed, so a signal may be unblocked for
2620 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2623 /* Because we don't use arg1 (newsetp) when this syscall is
2624 rerun, it doesn't matter that we overwrite it with the
2625 (constant) return value. */
2626 retval
= -cb_host_to_target_errno (cb
, EINTR
);
2627 sim_pc_set (current_cpu
, pc
);
2631 /* Add case labels here for other syscalls using the 32-bit
2632 "struct stat", provided they have a corresponding simulator
2633 function of course. */
2634 case TARGET_SYS_stat
:
2635 case TARGET_SYS_fstat
:
2637 /* As long as the infrastructure doesn't cache anything
2638 related to the stat mapping, this trick gets us a dual
2639 "struct stat"-type mapping in the least error-prone way. */
2640 const char *saved_map
= cb
->stat_map
;
2641 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
2643 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_stat32_map
;
2644 cb
->stat_map
= stat32_map
;
2646 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2649 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2652 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2654 cb
->stat_map
= saved_map
;
2655 cb
->syscall_map
= saved_syscall_map
;
2659 case TARGET_SYS_getcwd
:
2664 char *cwd
= xmalloc (SIM_PATHMAX
);
2665 if (cwd
!= getcwd (cwd
, SIM_PATHMAX
))
2668 /* FIXME: When and if we support chdir, we need something
2669 a bit more elaborate. */
2670 if (simulator_sysroot
[0] != '\0')
2673 retval
= -cb_host_to_target_errno (cb
, ERANGE
);
2674 if (strlen (cwd
) + 1 <= size
)
2676 retval
= strlen (cwd
) + 1;
2677 if (sim_core_write_buffer (sd
, current_cpu
, 0, cwd
,
2679 != (unsigned int) retval
)
2680 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2686 case TARGET_SYS_access
:
2690 char *pbuf
= xmalloc (SIM_PATHMAX
);
2695 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2697 strcpy (pbuf
, simulator_sysroot
);
2698 o
+= strlen (simulator_sysroot
);
2701 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2704 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2705 if (pbuf
[i
+ o
] == 0)
2709 if (i
+ o
== SIM_PATHMAX
)
2711 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2715 /* Assert that we don't get calls for files for which we
2716 don't have support. */
2717 if (strncmp (pbuf
+ strlen (simulator_sysroot
),
2720 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2727 if (access (pbuf
, hmode
) != 0)
2728 retval
= -cb_host_to_target_errno (cb
, errno
);
2736 case TARGET_SYS_readlink
:
2741 char *pbuf
= xmalloc (SIM_PATHMAX
);
2742 char *lbuf
= xmalloc (SIM_PATHMAX
);
2743 char *lbuf_alloc
= lbuf
;
2748 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2750 strcpy (pbuf
, simulator_sysroot
);
2751 o
+= strlen (simulator_sysroot
);
2754 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2757 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2758 if (pbuf
[i
+ o
] == 0)
2762 if (i
+ o
== SIM_PATHMAX
)
2764 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2768 /* Intervene calls for certain files expected in the target
2769 proc file system. */
2770 if (strcmp (pbuf
+ strlen (simulator_sysroot
),
2771 "/proc/" XSTRING (TARGET_PID
) "/exe") == 0)
2774 = (STATE_PROG_ARGV (sd
) != NULL
2775 ? *STATE_PROG_ARGV (sd
) : NULL
);
2777 if (argv0
== NULL
|| *argv0
== '.')
2780 = cris_unknown_syscall (current_cpu
, pc
,
2781 "Unimplemented readlink syscall "
2782 "(0x%lx: [\"%s\"], 0x%lx)\n",
2783 (unsigned long) arg1
, pbuf
,
2784 (unsigned long) arg2
);
2787 else if (*argv0
== '/')
2789 if (strncmp (simulator_sysroot
, argv0
,
2790 strlen (simulator_sysroot
)) == 0)
2791 argv0
+= strlen (simulator_sysroot
);
2793 strcpy (lbuf
, argv0
);
2794 nchars
= strlen (argv0
) + 1;
2798 if (getcwd (lbuf
, SIM_PATHMAX
) != NULL
2799 && strlen (lbuf
) + 2 + strlen (argv0
) < SIM_PATHMAX
)
2801 if (strncmp (simulator_sysroot
, lbuf
,
2802 strlen (simulator_sysroot
)) == 0)
2803 lbuf
+= strlen (simulator_sysroot
);
2806 strcat (lbuf
, argv0
);
2807 nchars
= strlen (lbuf
) + 1;
2814 nchars
= readlink (pbuf
, lbuf
, SIM_PATHMAX
);
2816 /* We trust that the readlink result returns a *relative*
2817 link, or one already adjusted for the file-path-prefix.
2818 (We can't generally tell the difference, so we go with
2819 the easiest decision; no adjustment.) */
2823 retval
= -cb_host_to_target_errno (cb
, errno
);
2827 if (bufsiz
< nchars
)
2830 if (sim_core_write_buffer (sd
, current_cpu
, write_map
, lbuf
,
2831 buf
, nchars
) != (unsigned int) nchars
)
2832 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2841 case TARGET_SYS_sched_getscheduler
:
2845 /* FIXME: Search (other) existing threads. */
2846 if (pid
!= 0 && pid
!= TARGET_PID
)
2847 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2849 retval
= TARGET_SCHED_OTHER
;
2853 case TARGET_SYS_sched_getparam
:
2859 struct sched_param {
2863 if (pid
!= 0 && pid
!= TARGET_PID
)
2864 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2867 /* FIXME: Save scheduler setting before threads are
2869 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, paramp
,
2870 current_cpu
->thread_data
!= NULL
2872 ->thread_data
[threadno
]
2880 case TARGET_SYS_sched_setparam
:
2885 if ((pid
!= 0 && pid
!= TARGET_PID
)
2886 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2888 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2894 case TARGET_SYS_sched_setscheduler
:
2900 if ((pid
!= 0 && pid
!= TARGET_PID
)
2901 || policy
!= TARGET_SCHED_OTHER
2902 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2904 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2906 /* FIXME: Save scheduler setting to be read in later
2907 sched_getparam calls. */
2912 case TARGET_SYS_sched_yield
:
2913 /* We reschedule to the next thread after a syscall anyway, so
2914 we don't have to do anything here than to set the return
2919 case TARGET_SYS_sched_get_priority_min
:
2920 case TARGET_SYS_sched_get_priority_max
:
2922 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2927 case TARGET_SYS_ugetrlimit
:
2929 unsigned int curlim
, maxlim
;
2930 if (arg1
!= TARGET_RLIMIT_STACK
&& arg1
!= TARGET_RLIMIT_NOFILE
)
2932 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2938 unsigned long rlim_cur;
2939 unsigned long rlim_max;
2941 if (arg1
== TARGET_RLIMIT_NOFILE
)
2943 /* Sadly a very low limit. Better not lie, though. */
2944 maxlim
= curlim
= MAX_CALLBACK_FDS
;
2946 else /* arg1 == TARGET_RLIMIT_STACK */
2948 maxlim
= 0xffffffff;
2951 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, curlim
);
2952 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, maxlim
);
2957 case TARGET_SYS_setrlimit
:
2958 if (arg1
!= TARGET_RLIMIT_STACK
)
2960 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2963 /* FIXME: Save values for future ugetrlimit calls. */
2967 /* Provide a very limited subset of the sysctl functions, and
2968 abort for the rest. */
2969 case TARGET_SYS__sysctl
:
2972 struct __sysctl_args {
2979 unsigned long __unused[4];
2981 SI name
= sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
);
2982 SI name0
= name
== 0
2983 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
);
2984 SI name1
= name
== 0
2985 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
+ 4);
2987 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4);
2989 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 8);
2991 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 12);
2992 SI oldlen
= oldlenp
== 0
2993 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, oldlenp
);
2995 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 16);
2997 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 20);
2999 if (name0
== TARGET_CTL_KERN
&& name1
== TARGET_CTL_KERN_VERSION
)
3001 SI to_write
= oldlen
< (SI
) sizeof (TARGET_UTSNAME
)
3002 ? oldlen
: (SI
) sizeof (TARGET_UTSNAME
);
3004 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldlenp
,
3005 sizeof (TARGET_UTSNAME
));
3007 if (sim_core_write_buffer (sd
, current_cpu
, write_map
,
3008 TARGET_UTSNAME
, oldval
,
3010 != (unsigned int) to_write
)
3011 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
3018 = cris_unknown_syscall (current_cpu
, pc
,
3019 "Unimplemented _sysctl syscall "
3020 "(0x%lx: [0x%lx, 0x%lx],"
3021 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
3022 (unsigned long) name
,
3023 (unsigned long) name0
,
3024 (unsigned long) name1
,
3025 (unsigned long) nlen
,
3026 (unsigned long) oldval
,
3027 (unsigned long) oldlenp
,
3028 (unsigned long) newval
,
3029 (unsigned long) newlen
);
3033 case TARGET_SYS_exit
:
3035 /* Here for all but the last thread. */
3038 = current_cpu
->thread_data
[threadno
].threadid
+ TARGET_PID
;
3040 = (current_cpu
->thread_data
[threadno
].parent_threadid
3042 int exitsig
= current_cpu
->thread_data
[threadno
].exitsig
;
3044 /* Any children are now all orphans. */
3045 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3046 if (current_cpu
->thread_data
[i
].parent_threadid
3047 == current_cpu
->thread_data
[threadno
].threadid
)
3048 /* Make getppid(2) return 1 for them, poor little ones. */
3049 current_cpu
->thread_data
[i
].parent_threadid
= -TARGET_PID
+ 1;
3051 /* Free the cpu context data. When the parent has received
3052 the exit status, we'll clear the entry too. */
3053 free (current_cpu
->thread_data
[threadno
].cpu_context
);
3054 current_cpu
->thread_data
[threadno
].cpu_context
= NULL
;
3055 current_cpu
->m1threads
--;
3058 sim_io_eprintf (sd
, "Thread %d exited with status %d\n",
3060 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
3064 /* Still, we may want to support non-zero exit values. */
3065 current_cpu
->thread_data
[threadno
].exitval
= arg1
<< 8;
3068 deliver_signal (current_cpu
, exitsig
, ppid
);
3072 case TARGET_SYS_clone
:
3074 int nthreads
= current_cpu
->m1threads
+ 1;
3075 void *thread_cpu_data
;
3076 bfd_byte old_sp_buf
[4];
3078 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3081 /* That's right, the syscall clone arguments are reversed
3082 compared to sys_clone notes in clone(2) and compared to
3083 other Linux ports (i.e. it's the same order as in the
3084 clone(2) libcall). */
3088 if (nthreads
== SIM_TARGET_MAX_THREADS
)
3090 retval
= -cb_host_to_target_errno (cb
, EAGAIN
);
3094 /* FIXME: Implement the low byte. */
3095 if ((flags
& ~TARGET_CSIGNAL
) !=
3098 | TARGET_CLONE_FILES
3099 | TARGET_CLONE_SIGHAND
)
3103 = cris_unknown_syscall (current_cpu
, pc
,
3104 "Unimplemented clone syscall "
3106 (unsigned long) arg1
,
3107 (unsigned long) arg2
);
3111 if (current_cpu
->thread_data
== NULL
)
3112 make_first_thread (current_cpu
);
3114 /* The created thread will get the new SP and a cleared R10.
3115 Since it's created out of a copy of the old thread and we
3116 don't have a set-register-function that just take the
3117 cpu_data as a parameter, we set the childs values first,
3118 and write back or overwrite them in the parent after the
3120 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
3121 H_GR_SP
, old_sp_buf
, 4);
3122 bfd_putl32 (newsp
, sp_buf
);
3123 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3124 H_GR_SP
, sp_buf
, 4);
3125 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3126 H_GR_R10
, (bfd_byte
*) zeros
, 4);
3129 ->make_thread_cpu_data
) (current_cpu
,
3130 ¤t_cpu
->cpu_data_placeholder
);
3131 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3132 H_GR_SP
, old_sp_buf
, 4);
3134 retval
= ++current_cpu
->max_threadid
+ TARGET_PID
;
3136 /* Find an unused slot. After a few threads have been created
3137 and exited, the array is expected to be a bit fragmented.
3138 We don't reuse the first entry, though, that of the
3140 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
3141 if (current_cpu
->thread_data
[i
].cpu_context
== NULL
3142 /* Don't reuse a zombied entry. */
3143 && current_cpu
->thread_data
[i
].threadid
== 0)
3146 memcpy (¤t_cpu
->thread_data
[i
],
3147 ¤t_cpu
->thread_data
[threadno
],
3148 sizeof (current_cpu
->thread_data
[i
]));
3149 current_cpu
->thread_data
[i
].cpu_context
= thread_cpu_data
;
3150 current_cpu
->thread_data
[i
].cpu_context_atsignal
= NULL
;
3151 current_cpu
->thread_data
[i
].threadid
= current_cpu
->max_threadid
;
3152 current_cpu
->thread_data
[i
].parent_threadid
3153 = current_cpu
->thread_data
[threadno
].threadid
;
3154 current_cpu
->thread_data
[i
].pipe_read_fd
= 0;
3155 current_cpu
->thread_data
[i
].pipe_write_fd
= 0;
3156 current_cpu
->thread_data
[i
].at_syscall
= 0;
3157 current_cpu
->thread_data
[i
].sigpending
= 0;
3158 current_cpu
->thread_data
[i
].sigsuspended
= 0;
3159 current_cpu
->thread_data
[i
].exitsig
= flags
& TARGET_CSIGNAL
;
3160 current_cpu
->m1threads
= nthreads
;
3164 /* Better watch these in case they do something necessary. */
3165 case TARGET_SYS_socketcall
:
3166 retval
= -cb_host_to_target_errno (cb
, ENOSYS
);
3169 case TARGET_SYS_set_thread_area
:
3170 /* Do the same error check as Linux. */
3173 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
3176 (*current_cpu
->set_target_thread_data
) (current_cpu
, arg1
);
3180 unimplemented_syscall
:
3183 = cris_unknown_syscall (current_cpu
, pc
,
3184 "Unimplemented syscall: %d "
3185 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3186 callnum
, arg1
, arg2
, arg3
, arg4
, arg5
,
3191 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
3192 if (callnum
== TARGET_SYS_open
)
3194 current_cpu
->last_open_fd
= retval
;
3195 current_cpu
->last_open_flags
= arg2
;
3198 current_cpu
->last_syscall
= callnum
;
3200 /* A system call is a rescheduling point. For the time being, we don't
3201 reschedule anywhere else. */
3202 if (current_cpu
->m1threads
!= 0
3203 /* We need to schedule off from an exiting thread that is the
3205 || (current_cpu
->thread_data
!= NULL
3206 && current_cpu
->thread_data
[threadno
].cpu_context
== NULL
))
3208 bfd_byte retval_buf
[4];
3210 current_cpu
->thread_data
[threadno
].last_execution
3211 = TARGET_TIME_MS (current_cpu
);
3212 bfd_putl32 (retval
, retval_buf
);
3213 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3215 current_cpu
->thread_data
[threadno
].at_syscall
= 1;
3216 reschedule (current_cpu
);
3218 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3219 retval
= bfd_getl32 (retval_buf
);
3225 /* Callback from simulator write saying that the pipe at (reader, writer)
3226 is now non-empty (so the writer should wait until the pipe is empty, at
3227 least not write to this or any other pipe). Simplest is to just wait
3228 until the pipe is empty. */
3231 cris_pipe_nonempty (host_callback
*cb ATTRIBUTE_UNUSED
,
3232 int reader
, int writer
)
3234 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3235 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3237 /* It's the current thread: we just have to re-run the current
3238 syscall instruction (presumably "break 13") and change the syscall
3239 to the special simulator-wait code. Oh, and set a marker that
3240 we're waiting, so we can disambiguate the special call from a
3243 This function may be called multiple times between cris_pipe_empty,
3244 but we must avoid e.g. decreasing PC every time. Check fd markers
3246 if (cpu
->thread_data
== NULL
)
3248 sim_io_eprintf (CPU_STATE (cpu
),
3249 "Terminating simulation due to writing pipe rd:wr %d:%d"
3250 " from one single thread\n", reader
, writer
);
3251 sim_engine_halt (CPU_STATE (cpu
), cpu
,
3252 NULL
, sim_pc_get (cpu
), sim_stopped
, SIM_SIGILL
);
3254 else if (cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
== 0)
3256 cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
= writer
;
3257 cpu
->thread_data
[cpu
->threadno
].pipe_read_fd
= reader
;
3258 /* FIXME: We really shouldn't change registers other than R10 in
3259 syscalls (like R9), here or elsewhere. */
3260 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R9
, (bfd_byte
*) zeros
, 4);
3261 sim_pc_set (cpu
, sim_pc_get (cpu
) - 2);
3265 /* Callback from simulator close or read call saying that the pipe at
3266 (reader, writer) is now empty (so the writer can write again, perhaps
3267 leave a waiting state). If there are bytes remaining, they couldn't be
3268 consumed (perhaps due to the pipe closing). */
3271 cris_pipe_empty (host_callback
*cb
,
3276 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3277 SIM_DESC sd
= CPU_STATE (current_cpu_for_cb_callback
);
3278 bfd_byte r10_buf
[4];
3280 = cb
->pipe_buffer
[writer
].size
- cb
->pipe_buffer
[reader
].size
;
3282 /* We need to find the thread that waits for this pipe. */
3283 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3284 if (cpu
->thread_data
[i
].cpu_context
3285 && cpu
->thread_data
[i
].pipe_write_fd
== writer
)
3289 /* Temporarily switch to this cpu context, so we can change the
3290 PC by ordinary calls. */
3292 memcpy (cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3293 &cpu
->cpu_data_placeholder
,
3294 cpu
->thread_cpu_data_size
);
3295 memcpy (&cpu
->cpu_data_placeholder
,
3296 cpu
->thread_data
[i
].cpu_context
,
3297 cpu
->thread_cpu_data_size
);
3299 /* The return value is supposed to contain the number of
3300 written bytes, which is the number of bytes requested and
3301 returned at the write call. You might think the right
3302 thing is to adjust the return-value to be only the
3303 *consumed* number of bytes, but it isn't. We're only
3304 called if the pipe buffer is fully consumed or it is being
3305 closed, possibly with remaining bytes. For the latter
3306 case, the writer is still supposed to see success for
3307 PIPE_BUF bytes (a constant which we happen to know and is
3308 unlikely to change). The return value may also be a
3309 negative number; an error value. This case is covered
3310 because "remaining" is always >= 0. */
3311 (*CPU_REG_FETCH (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3312 retval
= (int) bfd_getl_signed_32 (r10_buf
);
3313 if (retval
- remaining
> TARGET_PIPE_BUF
)
3315 bfd_putl32 (retval
- remaining
, r10_buf
);
3316 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3318 sim_pc_set (cpu
, sim_pc_get (cpu
) + 2);
3319 memcpy (cpu
->thread_data
[i
].cpu_context
,
3320 &cpu
->cpu_data_placeholder
,
3321 cpu
->thread_cpu_data_size
);
3322 memcpy (&cpu
->cpu_data_placeholder
,
3323 cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3324 cpu
->thread_cpu_data_size
);
3325 cpu
->thread_data
[i
].pipe_read_fd
= 0;
3326 cpu
->thread_data
[i
].pipe_write_fd
= 0;
3333 /* We have a simulator-specific notion of time. See TARGET_TIME. */
3336 cris_time (host_callback
*cb ATTRIBUTE_UNUSED
)
3338 return TARGET_TIME (current_cpu_for_cb_callback
);
3341 /* Set target-specific callback data. */
3344 cris_set_callbacks (host_callback
*cb
)
3346 /* Yeargh, have to cast away constness to avoid warnings. */
3347 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_map
;
3348 cb
->errno_map
= (CB_TARGET_DEFS_MAP
*) errno_map
;
3350 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3351 parameter to cb_store_target_endian will make st_size negative.
3352 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3353 *unsigned*, and/or add syntax for signed-ness. */
3354 cb
->stat_map
= stat_map
;
3355 cb
->open_map
= (CB_TARGET_DEFS_MAP
*) open_map
;
3356 cb
->pipe_nonempty
= cris_pipe_nonempty
;
3357 cb
->pipe_empty
= cris_pipe_empty
;
3358 cb
->time
= cris_time
;
3361 /* Process an address exception. */
3364 cris_core_signal (SIM_DESC sd
, SIM_CPU
*current_cpu
, sim_cia cia
,
3365 unsigned int map
, int nr_bytes
, address_word addr
,
3366 transfer_type transfer
, sim_core_signals sig
)
3368 sim_core_signal (sd
, current_cpu
, cia
, map
, nr_bytes
, addr
,