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/>. */
21 #include "sim-syscall.h"
22 #include "sim-options.h"
24 /* FIXME: get rid of targ-vals.h usage everywhere else. */
34 #ifdef HAVE_SYS_PARAM_H
35 #include <sys/param.h>
37 #ifdef HAVE_SYS_STAT_H
40 /* For PATH_MAX, originally. */
45 /* From ld/sysdep.h. */
47 # define SIM_PATHMAX PATH_MAX
50 # define SIM_PATHMAX MAXPATHLEN
52 # define SIM_PATHMAX 1024
56 /* The verbatim values are from asm-cris/unistd.h. */
58 #define TARGET_SYS_exit 1
59 #define TARGET_SYS_read 3
60 #define TARGET_SYS_write 4
61 #define TARGET_SYS_open 5
62 #define TARGET_SYS_close 6
63 #define TARGET_SYS_unlink 10
64 #define TARGET_SYS_time 13
65 #define TARGET_SYS_lseek 19
66 #define TARGET_SYS_getpid 20
67 #define TARGET_SYS_access 33
68 #define TARGET_SYS_kill 37
69 #define TARGET_SYS_rename 38
70 #define TARGET_SYS_pipe 42
71 #define TARGET_SYS_brk 45
72 #define TARGET_SYS_ioctl 54
73 #define TARGET_SYS_fcntl 55
74 #define TARGET_SYS_getppid 64
75 #define TARGET_SYS_setrlimit 75
76 #define TARGET_SYS_gettimeofday 78
77 #define TARGET_SYS_readlink 85
78 #define TARGET_SYS_munmap 91
79 #define TARGET_SYS_truncate 92
80 #define TARGET_SYS_ftruncate 93
81 #define TARGET_SYS_socketcall 102
82 #define TARGET_SYS_stat 106
83 #define TARGET_SYS_fstat 108
84 #define TARGET_SYS_wait4 114
85 #define TARGET_SYS_sigreturn 119
86 #define TARGET_SYS_clone 120
87 #define TARGET_SYS_uname 122
88 #define TARGET_SYS_mprotect 125
89 #define TARGET_SYS_llseek 140
90 #define TARGET_SYS_writev 146
91 #define TARGET_SYS__sysctl 149
92 #define TARGET_SYS_sched_setparam 154
93 #define TARGET_SYS_sched_getparam 155
94 #define TARGET_SYS_sched_setscheduler 156
95 #define TARGET_SYS_sched_getscheduler 157
96 #define TARGET_SYS_sched_yield 158
97 #define TARGET_SYS_sched_get_priority_max 159
98 #define TARGET_SYS_sched_get_priority_min 160
99 #define TARGET_SYS_mremap 163
100 #define TARGET_SYS_poll 168
101 #define TARGET_SYS_rt_sigaction 174
102 #define TARGET_SYS_rt_sigprocmask 175
103 #define TARGET_SYS_rt_sigsuspend 179
104 #define TARGET_SYS_getcwd 183
105 #define TARGET_SYS_ugetrlimit 191
106 #define TARGET_SYS_mmap2 192
107 #define TARGET_SYS_stat64 195
108 #define TARGET_SYS_lstat64 196
109 #define TARGET_SYS_fstat64 197
110 #define TARGET_SYS_geteuid32 201
111 #define TARGET_SYS_getuid32 199
112 #define TARGET_SYS_getegid32 202
113 #define TARGET_SYS_getgid32 200
114 #define TARGET_SYS_fcntl64 221
115 #define TARGET_SYS_set_thread_area 243
116 #define TARGET_SYS_exit_group 252
118 #define TARGET_PROT_READ 0x1
119 #define TARGET_PROT_WRITE 0x2
120 #define TARGET_PROT_EXEC 0x4
121 #define TARGET_PROT_NONE 0x0
123 #define TARGET_MAP_SHARED 0x01
124 #define TARGET_MAP_PRIVATE 0x02
125 #define TARGET_MAP_TYPE 0x0f
126 #define TARGET_MAP_FIXED 0x10
127 #define TARGET_MAP_ANONYMOUS 0x20
128 #define TARGET_MAP_DENYWRITE 0x800
130 #define TARGET_CTL_KERN 1
131 #define TARGET_CTL_VM 2
132 #define TARGET_CTL_NET 3
133 #define TARGET_CTL_PROC 4
134 #define TARGET_CTL_FS 5
135 #define TARGET_CTL_DEBUG 6
136 #define TARGET_CTL_DEV 7
137 #define TARGET_CTL_BUS 8
138 #define TARGET_CTL_ABI 9
140 #define TARGET_CTL_KERN_VERSION 4
143 #define TARGET_MREMAP_MAYMOVE 1
144 #define TARGET_MREMAP_FIXED 2
146 #define TARGET_TCGETS 0x5401
148 #define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
150 /* Seconds since 1970-01-01 to the above date + 10 minutes;
151 'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'. */
152 #define TARGET_EPOCH 1230764410
154 /* Milliseconds since start of run. We use the number of syscalls to
155 avoid introducing noise in the execution time. */
156 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
158 /* Seconds as in time(2). */
159 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
161 #define TARGET_SCHED_OTHER 0
163 #define TARGET_RLIMIT_STACK 3
164 #define TARGET_RLIMIT_NOFILE 7
166 #define SIM_TARGET_MAX_THREADS 64
167 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
169 /* From linux/sched.h. */
170 #define TARGET_CSIGNAL 0x000000ff
171 #define TARGET_CLONE_VM 0x00000100
172 #define TARGET_CLONE_FS 0x00000200
173 #define TARGET_CLONE_FILES 0x00000400
174 #define TARGET_CLONE_SIGHAND 0x00000800
175 #define TARGET_CLONE_PID 0x00001000
176 #define TARGET_CLONE_PTRACE 0x00002000
177 #define TARGET_CLONE_VFORK 0x00004000
178 #define TARGET_CLONE_PARENT 0x00008000
179 #define TARGET_CLONE_THREAD 0x00010000
180 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
182 /* From asm-cris/poll.h. */
183 #define TARGET_POLLIN 1
185 /* From asm-cris/signal.h. */
186 #define TARGET_SIG_BLOCK 0
187 #define TARGET_SIG_UNBLOCK 1
188 #define TARGET_SIG_SETMASK 2
190 #define TARGET_SIG_DFL 0
191 #define TARGET_SIG_IGN 1
192 #define TARGET_SIG_ERR ((USI)-1)
194 #define TARGET_SIGHUP 1
195 #define TARGET_SIGINT 2
196 #define TARGET_SIGQUIT 3
197 #define TARGET_SIGILL 4
198 #define TARGET_SIGTRAP 5
199 #define TARGET_SIGABRT 6
200 #define TARGET_SIGIOT 6
201 #define TARGET_SIGBUS 7
202 #define TARGET_SIGFPE 8
203 #define TARGET_SIGKILL 9
204 #define TARGET_SIGUSR1 10
205 #define TARGET_SIGSEGV 11
206 #define TARGET_SIGUSR2 12
207 #define TARGET_SIGPIPE 13
208 #define TARGET_SIGALRM 14
209 #define TARGET_SIGTERM 15
210 #define TARGET_SIGSTKFLT 16
211 #define TARGET_SIGCHLD 17
212 #define TARGET_SIGCONT 18
213 #define TARGET_SIGSTOP 19
214 #define TARGET_SIGTSTP 20
215 #define TARGET_SIGTTIN 21
216 #define TARGET_SIGTTOU 22
217 #define TARGET_SIGURG 23
218 #define TARGET_SIGXCPU 24
219 #define TARGET_SIGXFSZ 25
220 #define TARGET_SIGVTALRM 26
221 #define TARGET_SIGPROF 27
222 #define TARGET_SIGWINCH 28
223 #define TARGET_SIGIO 29
224 #define TARGET_SIGPOLL SIGIO
225 /* Actually commented out in the kernel header. */
226 #define TARGET_SIGLOST 29
227 #define TARGET_SIGPWR 30
228 #define TARGET_SIGSYS 31
230 /* From include/asm-cris/signal.h. */
231 #define TARGET_SA_NOCLDSTOP 0x00000001
232 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
233 #define TARGET_SA_SIGINFO 0x00000004
234 #define TARGET_SA_ONSTACK 0x08000000
235 #define TARGET_SA_RESTART 0x10000000
236 #define TARGET_SA_NODEFER 0x40000000
237 #define TARGET_SA_RESETHAND 0x80000000
238 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
239 #define TARGET_SA_RESTORER 0x04000000
241 /* From linux/wait.h. */
242 #define TARGET_WNOHANG 1
243 #define TARGET_WUNTRACED 2
244 #define TARGET___WNOTHREAD 0x20000000
245 #define TARGET___WALL 0x40000000
246 #define TARGET___WCLONE 0x80000000
248 /* From linux/limits.h. */
249 #define TARGET_PIPE_BUF 4096
252 #define TARGET_R_OK 4
253 #define TARGET_W_OK 2
254 #define TARGET_X_OK 1
255 #define TARGET_F_OK 0
257 static const char stat_map
[] =
258 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
259 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
260 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
263 static const CB_TARGET_DEFS_MAP syscall_map
[] =
265 { "open", CB_SYS_open
, TARGET_SYS_open
},
266 { "close", CB_SYS_close
, TARGET_SYS_close
},
267 { "read", CB_SYS_read
, TARGET_SYS_read
},
268 { "write", CB_SYS_write
, TARGET_SYS_write
},
269 { "lseek", CB_SYS_lseek
, TARGET_SYS_lseek
},
270 { "unlink", CB_SYS_unlink
, TARGET_SYS_unlink
},
271 { "getpid", CB_SYS_getpid
, TARGET_SYS_getpid
},
272 { "fstat", CB_SYS_fstat
, TARGET_SYS_fstat64
},
273 { "lstat", CB_SYS_lstat
, TARGET_SYS_lstat64
},
274 { "stat", CB_SYS_stat
, TARGET_SYS_stat64
},
275 { "pipe", CB_SYS_pipe
, TARGET_SYS_pipe
},
276 { "rename", CB_SYS_rename
, TARGET_SYS_rename
},
277 { "truncate", CB_SYS_truncate
, TARGET_SYS_truncate
},
278 { "ftruncate", CB_SYS_ftruncate
, TARGET_SYS_ftruncate
},
282 /* An older, 32-bit-only stat mapping. */
283 static const char stat32_map
[] =
284 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
285 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
286 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
288 /* Map for calls using the 32-bit struct stat. Primarily used by the
289 newlib Linux mapping. */
290 static const CB_TARGET_DEFS_MAP syscall_stat32_map
[] =
292 { "fstat", CB_SYS_fstat
, TARGET_SYS_fstat
},
293 { "stat", CB_SYS_stat
, TARGET_SYS_stat
},
297 /* Giving the true value for the running sim process will lead to
298 non-time-invariant behavior. */
299 #define TARGET_PID 42
301 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
302 we did, we'd still don't get a register number with the "16" offset. */
303 #define TARGET_SRP_REGNUM (16+11)
305 /* Extracted by applying
306 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
307 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
308 adjusting the synonyms. */
310 static const CB_TARGET_DEFS_MAP errno_map
[] =
313 { "EPERM", EPERM
, 1 },
316 { "ENOENT", ENOENT
, 2 },
319 { "ESRCH", ESRCH
, 3 },
322 { "EINTR", EINTR
, 4 },
328 { "ENXIO", ENXIO
, 6 },
331 { "E2BIG", E2BIG
, 7 },
334 { "ENOEXEC", ENOEXEC
, 8 },
337 { "EBADF", EBADF
, 9 },
340 { "ECHILD", ECHILD
, 10 },
343 { "EAGAIN", EAGAIN
, 11 },
346 { "ENOMEM", ENOMEM
, 12 },
349 { "EACCES", EACCES
, 13 },
352 { "EFAULT", EFAULT
, 14 },
355 { "ENOTBLK", ENOTBLK
, 15 },
358 { "EBUSY", EBUSY
, 16 },
361 { "EEXIST", EEXIST
, 17 },
364 { "EXDEV", EXDEV
, 18 },
367 { "ENODEV", ENODEV
, 19 },
370 { "ENOTDIR", ENOTDIR
, 20 },
373 { "EISDIR", EISDIR
, 21 },
376 { "EINVAL", EINVAL
, 22 },
379 { "ENFILE", ENFILE
, 23 },
382 { "EMFILE", EMFILE
, 24 },
385 { "ENOTTY", ENOTTY
, 25 },
388 { "ETXTBSY", ETXTBSY
, 26 },
391 { "EFBIG", EFBIG
, 27 },
394 { "ENOSPC", ENOSPC
, 28 },
397 { "ESPIPE", ESPIPE
, 29 },
400 { "EROFS", EROFS
, 30 },
403 { "EMLINK", EMLINK
, 31 },
406 { "EPIPE", EPIPE
, 32 },
409 { "EDOM", EDOM
, 33 },
412 { "ERANGE", ERANGE
, 34 },
415 { "EDEADLK", EDEADLK
, 35 },
418 { "ENAMETOOLONG", ENAMETOOLONG
, 36 },
421 { "ENOLCK", ENOLCK
, 37 },
424 { "ENOSYS", ENOSYS
, 38 },
427 { "ENOTEMPTY", ENOTEMPTY
, 39 },
430 { "ELOOP", ELOOP
, 40 },
433 { "EWOULDBLOCK", EWOULDBLOCK
, 11 },
436 { "ENOMSG", ENOMSG
, 42 },
439 { "EIDRM", EIDRM
, 43 },
442 { "ECHRNG", ECHRNG
, 44 },
445 { "EL2NSYNC", EL2NSYNC
, 45 },
448 { "EL3HLT", EL3HLT
, 46 },
451 { "EL3RST", EL3RST
, 47 },
454 { "ELNRNG", ELNRNG
, 48 },
457 { "EUNATCH", EUNATCH
, 49 },
460 { "ENOCSI", ENOCSI
, 50 },
463 { "EL2HLT", EL2HLT
, 51 },
466 { "EBADE", EBADE
, 52 },
469 { "EBADR", EBADR
, 53 },
472 { "EXFULL", EXFULL
, 54 },
475 { "ENOANO", ENOANO
, 55 },
478 { "EBADRQC", EBADRQC
, 56 },
481 { "EBADSLT", EBADSLT
, 57 },
484 { "EDEADLOCK", EDEADLOCK
, 35 },
487 { "EBFONT", EBFONT
, 59 },
490 { "ENOSTR", ENOSTR
, 60 },
493 { "ENODATA", ENODATA
, 61 },
496 { "ETIME", ETIME
, 62 },
499 { "ENOSR", ENOSR
, 63 },
502 { "ENONET", ENONET
, 64 },
505 { "ENOPKG", ENOPKG
, 65 },
508 { "EREMOTE", EREMOTE
, 66 },
511 { "ENOLINK", ENOLINK
, 67 },
514 { "EADV", EADV
, 68 },
517 { "ESRMNT", ESRMNT
, 69 },
520 { "ECOMM", ECOMM
, 70 },
523 { "EPROTO", EPROTO
, 71 },
526 { "EMULTIHOP", EMULTIHOP
, 72 },
529 { "EDOTDOT", EDOTDOT
, 73 },
532 { "EBADMSG", EBADMSG
, 74 },
535 { "EOVERFLOW", EOVERFLOW
, 75 },
538 { "ENOTUNIQ", ENOTUNIQ
, 76 },
541 { "EBADFD", EBADFD
, 77 },
544 { "EREMCHG", EREMCHG
, 78 },
547 { "ELIBACC", ELIBACC
, 79 },
550 { "ELIBBAD", ELIBBAD
, 80 },
553 { "ELIBSCN", ELIBSCN
, 81 },
556 { "ELIBMAX", ELIBMAX
, 82 },
559 { "ELIBEXEC", ELIBEXEC
, 83 },
562 { "EILSEQ", EILSEQ
, 84 },
565 { "ERESTART", ERESTART
, 85 },
568 { "ESTRPIPE", ESTRPIPE
, 86 },
571 { "EUSERS", EUSERS
, 87 },
574 { "ENOTSOCK", ENOTSOCK
, 88 },
577 { "EDESTADDRREQ", EDESTADDRREQ
, 89 },
580 { "EMSGSIZE", EMSGSIZE
, 90 },
583 { "EPROTOTYPE", EPROTOTYPE
, 91 },
586 { "ENOPROTOOPT", ENOPROTOOPT
, 92 },
588 #ifdef EPROTONOSUPPORT
589 { "EPROTONOSUPPORT", EPROTONOSUPPORT
, 93 },
591 #ifdef ESOCKTNOSUPPORT
592 { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT
, 94 },
595 { "EOPNOTSUPP", EOPNOTSUPP
, 95 },
598 { "EPFNOSUPPORT", EPFNOSUPPORT
, 96 },
601 { "EAFNOSUPPORT", EAFNOSUPPORT
, 97 },
604 { "EADDRINUSE", EADDRINUSE
, 98 },
607 { "EADDRNOTAVAIL", EADDRNOTAVAIL
, 99 },
610 { "ENETDOWN", ENETDOWN
, 100 },
613 { "ENETUNREACH", ENETUNREACH
, 101 },
616 { "ENETRESET", ENETRESET
, 102 },
619 { "ECONNABORTED", ECONNABORTED
, 103 },
622 { "ECONNRESET", ECONNRESET
, 104 },
625 { "ENOBUFS", ENOBUFS
, 105 },
628 { "EISCONN", EISCONN
, 106 },
631 { "ENOTCONN", ENOTCONN
, 107 },
634 { "ESHUTDOWN", ESHUTDOWN
, 108 },
637 { "ETOOMANYREFS", ETOOMANYREFS
, 109 },
640 { "ETIMEDOUT", ETIMEDOUT
, 110 },
643 { "ECONNREFUSED", ECONNREFUSED
, 111 },
646 { "EHOSTDOWN", EHOSTDOWN
, 112 },
649 { "EHOSTUNREACH", EHOSTUNREACH
, 113 },
652 { "EALREADY", EALREADY
, 114 },
655 { "EINPROGRESS", EINPROGRESS
, 115 },
658 { "ESTALE", ESTALE
, 116 },
661 { "EUCLEAN", EUCLEAN
, 117 },
664 { "ENOTNAM", ENOTNAM
, 118 },
667 { "ENAVAIL", ENAVAIL
, 119 },
670 { "EISNAM", EISNAM
, 120 },
673 { "EREMOTEIO", EREMOTEIO
, 121 },
676 { "EDQUOT", EDQUOT
, 122 },
679 { "ENOMEDIUM", ENOMEDIUM
, 123 },
682 { "EMEDIUMTYPE", EMEDIUMTYPE
, 124 },
687 /* Extracted by applying
688 perl -ne 'if ($_ =~ /^#define/) { split;
689 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
690 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
691 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
692 installation and removing synonyms and unnecessary items. Don't
693 forget the end-marker. */
695 /* These we treat specially, as they're used in the fcntl F_GETFL
696 syscall. For consistency, open_map is also manually edited to use
698 #define TARGET_O_ACCMODE 0x3
699 #define TARGET_O_RDONLY 0x0
700 #define TARGET_O_WRONLY 0x1
702 static const CB_TARGET_DEFS_MAP open_map
[] = {
704 { "O_ACCMODE", O_ACCMODE
, TARGET_O_ACCMODE
},
707 { "O_RDONLY", O_RDONLY
, TARGET_O_RDONLY
},
710 { "O_WRONLY", O_WRONLY
, TARGET_O_WRONLY
},
713 { "O_RDWR", O_RDWR
, 0x2 },
716 { "O_CREAT", O_CREAT
, 0x40 },
719 { "O_EXCL", O_EXCL
, 0x80 },
722 { "O_NOCTTY", O_NOCTTY
, 0x100 },
725 { "O_TRUNC", O_TRUNC
, 0x200 },
728 { "O_APPEND", O_APPEND
, 0x400 },
731 { "O_NONBLOCK", O_NONBLOCK
, 0x800 },
734 { "O_NDELAY", O_NDELAY
, 0x0 },
737 { "O_SYNC", O_SYNC
, 0x1000 },
740 { "FASYNC", FASYNC
, 0x2000 },
743 { "O_DIRECT", O_DIRECT
, 0x4000 },
746 { "O_LARGEFILE", O_LARGEFILE
, 0x8000 },
749 { "O_DIRECTORY", O_DIRECTORY
, 0x10000 },
752 { "O_NOFOLLOW", O_NOFOLLOW
, 0x20000 },
757 /* Let's be less drastic and more traceable. FIXME: mark as noreturn. */
759 sim_io_error (sd, "simulator unhandled condition at %s:%d", \
760 __FUNCTION__, __LINE__)
762 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
763 static SIM_CPU
*current_cpu_for_cb_callback
;
765 static USI
create_map (SIM_DESC
, struct cris_sim_mmapped_page
**,
767 static USI
unmap_pages (SIM_DESC
, struct cris_sim_mmapped_page
**,
769 static USI
is_mapped (SIM_DESC
, struct cris_sim_mmapped_page
**,
771 static void dump_statistics (SIM_CPU
*current_cpu
);
772 static void make_first_thread (SIM_CPU
*current_cpu
);
774 /* When we risk running self-modified code (as in trampolines), this is
775 called from special-case insns. The silicon CRIS CPU:s have enough
776 cache snooping implemented making this a simulator-only issue. Tests:
777 gcc.c-torture/execute/931002-1.c execution, -O3 -g
778 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
781 cris_flush_simulator_decode_cache (SIM_CPU
*current_cpu
,
782 USI pc ATTRIBUTE_UNUSED
)
784 SIM_DESC sd
= CPU_STATE (current_cpu
);
787 if (USING_SCACHE_P (sd
))
788 scache_flush_cpu (current_cpu
);
792 /* Output statistics at the end of a run. */
794 dump_statistics (SIM_CPU
*current_cpu
)
796 SIM_DESC sd
= CPU_STATE (current_cpu
);
797 CRIS_MISC_PROFILE
*profp
798 = CPU_CRIS_MISC_PROFILE (current_cpu
);
799 unsigned64 total
= profp
->basic_cycle_count
;
800 const char *textmsg
= "Basic clock cycles, total @: %llu\n";
802 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
803 what's included in the "total" count only. */
804 switch (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
805 & FLAG_CRIS_MISC_PROFILE_ALL
)
807 case FLAG_CRIS_MISC_PROFILE_SIMPLE
:
810 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
812 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
813 total
+= profp
->unaligned_mem_dword_count
;
816 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
817 textmsg
= "Schedulable clock cycles, total @: %llu\n";
819 += (profp
->memsrc_stall_count
820 + profp
->memraw_stall_count
821 + profp
->movemsrc_stall_count
822 + profp
->movemdst_stall_count
823 + profp
->mulsrc_stall_count
824 + profp
->jumpsrc_stall_count
825 + profp
->unaligned_mem_dword_count
);
828 case FLAG_CRIS_MISC_PROFILE_ALL
:
829 textmsg
= "All accounted clock cycles, total @: %llu\n";
831 += (profp
->memsrc_stall_count
832 + profp
->memraw_stall_count
833 + profp
->movemsrc_stall_count
834 + profp
->movemdst_stall_count
835 + profp
->movemaddr_stall_count
836 + profp
->mulsrc_stall_count
837 + profp
->jumpsrc_stall_count
838 + profp
->branch_stall_count
839 + profp
->jumptarget_stall_count
840 + profp
->unaligned_mem_dword_count
);
847 "Internal inconsistency at %s:%d",
849 sim_engine_halt (sd
, current_cpu
, NULL
, 0,
850 sim_stopped
, SIM_SIGILL
);
853 /* Historically, these messages have gone to stderr, so we'll keep it
854 that way. It's also easier to then tell it from normal program
855 output. FIXME: Add redirect option like "run -e file". */
856 sim_io_eprintf (sd
, textmsg
, total
);
858 /* For v32, unaligned_mem_dword_count should always be 0. For
859 v10, memsrc_stall_count should always be 0. */
860 sim_io_eprintf (sd
, "Memory source stall cycles: %llu\n",
861 (unsigned long long) (profp
->memsrc_stall_count
862 + profp
->unaligned_mem_dword_count
));
863 sim_io_eprintf (sd
, "Memory read-after-write stall cycles: %llu\n",
864 (unsigned long long) profp
->memraw_stall_count
);
865 sim_io_eprintf (sd
, "Movem source stall cycles: %llu\n",
866 (unsigned long long) profp
->movemsrc_stall_count
);
867 sim_io_eprintf (sd
, "Movem destination stall cycles: %llu\n",
868 (unsigned long long) profp
->movemdst_stall_count
);
869 sim_io_eprintf (sd
, "Movem address stall cycles: %llu\n",
870 (unsigned long long) profp
->movemaddr_stall_count
);
871 sim_io_eprintf (sd
, "Multiplication source stall cycles: %llu\n",
872 (unsigned long long) profp
->mulsrc_stall_count
);
873 sim_io_eprintf (sd
, "Jump source stall cycles: %llu\n",
874 (unsigned long long) profp
->jumpsrc_stall_count
);
875 sim_io_eprintf (sd
, "Branch misprediction stall cycles: %llu\n",
876 (unsigned long long) profp
->branch_stall_count
);
877 sim_io_eprintf (sd
, "Jump target stall cycles: %llu\n",
878 (unsigned long long) profp
->jumptarget_stall_count
);
881 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
882 Return 1 if a overlap detected, 0 otherwise. */
885 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED
,
886 struct cris_sim_mmapped_page
**rootp
,
889 struct cris_sim_mmapped_page
*mapp
;
891 if (len
== 0 || (len
& 8191))
894 /* Iterate over the reverse-address sorted pages until we find a page in
895 or lower than the checked area. */
896 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
897 if (mapp
->addr
< addr
+ len
&& mapp
->addr
>= addr
)
903 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
904 Return 1 if the whole area is mapped, 0 otherwise. */
907 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED
,
908 struct cris_sim_mmapped_page
**rootp
,
911 struct cris_sim_mmapped_page
*mapp
;
913 if (len
== 0 || (len
& 8191))
916 /* Iterate over the reverse-address sorted pages until we find a page
917 lower than the checked area. */
918 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
919 if (addr
== mapp
->addr
&& len
== 8192)
921 else if (addr
+ len
> mapp
->addr
)
927 /* Debug helper; to be run from gdb. */
930 cris_dump_map (SIM_CPU
*current_cpu
)
932 struct cris_sim_mmapped_page
*mapp
;
935 for (mapp
= current_cpu
->highest_mmapped_page
,
936 start
= mapp
== NULL
? 0 : mapp
->addr
+ 8192,
937 end
= mapp
== NULL
? 0 : mapp
->addr
+ 8191;
941 if (mapp
->addr
!= start
- 8192)
943 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
944 end
= mapp
->addr
+ 8191;
950 if (current_cpu
->highest_mmapped_page
!= NULL
)
951 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
954 /* Create mmapped memory. ADDR is -1 if any address will do. Caller
955 must make sure that the address isn't already mapped. */
958 create_map (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
961 struct cris_sim_mmapped_page
*mapp
;
962 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
963 USI new_addr
= 0x40000000;
965 if (addr
!= (USI
) -1)
967 else if (*rootp
&& rootp
[0]->addr
>= new_addr
)
968 new_addr
= rootp
[0]->addr
+ 8192;
975 /* Which is better: return an error for this, or just round it up? */
978 /* Do a recursive call for each page in the request. */
979 for (page_addr
= new_addr
; len
!= 0; page_addr
+= 8192, len
-= 8192)
980 if (create_map (sd
, rootp
, page_addr
, 8192) >= (USI
) -8191)
987 mapp
!= NULL
&& mapp
->addr
> new_addr
;
989 higher_prevp
= &mapp
->prev
;
991 /* Assert for consistency that we don't create duplicate maps. */
992 if (is_mapped (sd
, rootp
, new_addr
, len
))
995 /* Allocate the new page, on the next higher page from the last one
996 allocated, and link in the new descriptor before previous ones. */
997 mapp
= malloc (sizeof (*mapp
));
1000 return (USI
) -ENOMEM
;
1002 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1006 mapp
->addr
= new_addr
;
1007 mapp
->prev
= *higher_prevp
;
1008 *higher_prevp
= mapp
;
1013 /* Unmap one or more pages. */
1016 unmap_pages (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
1019 struct cris_sim_mmapped_page
*mapp
;
1020 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
1028 /* Which is better: return an error for this, or just round it up? */
1031 /* Loop backwards to make each call is O(1) over the number of pages
1032 allocated, if we're unmapping from the high end of the pages. */
1033 for (page_addr
= addr
+ len
- 8192;
1036 if (unmap_pages (sd
, rootp
, page_addr
, 8192))
1039 if (unmap_pages (sd
, rootp
, addr
, 8192))
1045 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
> addr
; mapp
= mapp
->prev
)
1046 higher_prevp
= &mapp
->prev
;
1048 if (mapp
== NULL
|| mapp
->addr
!= addr
)
1051 *higher_prevp
= mapp
->prev
;
1052 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1057 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1060 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC vpc
)
1062 SIM_DESC sd
= CPU_STATE (current_cpu
);
1064 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
1068 /* Handlers from the CGEN description that should not be called. */
1071 cris_bmod_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1072 UINT srcreg ATTRIBUTE_UNUSED
,
1073 USI dstreg ATTRIBUTE_UNUSED
)
1075 SIM_DESC sd
= CPU_STATE (current_cpu
);
1080 h_supr_set_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1081 UINT index ATTRIBUTE_UNUSED
,
1082 USI page ATTRIBUTE_UNUSED
,
1083 USI newval ATTRIBUTE_UNUSED
)
1085 SIM_DESC sd
= CPU_STATE (current_cpu
);
1090 h_supr_get_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1091 UINT index ATTRIBUTE_UNUSED
,
1092 USI page ATTRIBUTE_UNUSED
)
1094 SIM_DESC sd
= CPU_STATE (current_cpu
);
1098 /* Swap one context for another. */
1101 schedule (SIM_CPU
*current_cpu
, int next
)
1103 /* Need to mark context-switches in the trace output. */
1104 if ((CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1105 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE
))
1106 cris_trace_printf (CPU_STATE (current_cpu
), current_cpu
,
1109 /* Copy the current context (if there is one) to its slot. */
1110 if (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
)
1111 memcpy (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
,
1112 ¤t_cpu
->cpu_data_placeholder
,
1113 current_cpu
->thread_cpu_data_size
);
1115 /* Copy the new context from its slot. */
1116 memcpy (¤t_cpu
->cpu_data_placeholder
,
1117 current_cpu
->thread_data
[next
].cpu_context
,
1118 current_cpu
->thread_cpu_data_size
);
1120 /* Update needed stuff to indicate the new context. */
1121 current_cpu
->threadno
= next
;
1123 /* Handle pending signals. */
1124 if (current_cpu
->thread_data
[next
].sigpending
1125 /* We don't run nested signal handlers. This means that pause(2)
1126 and sigsuspend(2) do not work in sighandlers, but that
1127 shouldn't be too hard a restriction. It also greatly
1128 simplifies the code. */
1129 && current_cpu
->thread_data
[next
].cpu_context_atsignal
== NULL
)
1133 /* See if there's really a pending, non-blocked handler. We don't
1134 queue signals, so just use the first one in ascending order. */
1135 for (sig
= 0; sig
< 64; sig
++)
1136 if (current_cpu
->thread_data
[next
].sigdata
[sig
].pending
1137 && !current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
)
1143 USI pc
= sim_pc_get (current_cpu
);
1145 /* It's simpler to save the CPU context inside the simulator
1146 than on the stack. */
1147 current_cpu
->thread_data
[next
].cpu_context_atsignal
1149 ->make_thread_cpu_data
) (current_cpu
,
1150 current_cpu
->thread_data
[next
]
1153 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1154 sp
= bfd_getl32 (regbuf
);
1156 /* Make sure we have an aligned stack. */
1159 /* Make room for the signal frame, aligned. FIXME: Check that
1160 the memory exists, map it in if absent. (BTW, should also
1161 implement on-access automatic stack allocation). */
1164 /* This isn't the same signal frame as the kernel uses, because
1165 we don't want to bother getting all registers on and off the
1168 /* First, we store the currently blocked signals. */
1170 for (i
= 0; i
< 32; i
++)
1172 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 1].blocked
<< i
;
1173 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
, blocked
);
1175 for (i
= 0; i
< 31; i
++)
1177 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 33].blocked
<< i
;
1178 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
+ 4, blocked
);
1180 /* Then, the actual instructions. This is CPU-specific, but we
1181 use instructions from the common subset for v10 and v32 which
1182 should be safe for the time being but could be parametrized
1184 /* MOVU.W [PC+],R9. */
1185 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 8, 0x9c5f);
1186 /* .WORD TARGET_SYS_sigreturn. */
1187 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 10,
1188 TARGET_SYS_sigreturn
);
1190 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 12, 0xe93d);
1192 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1193 instruction. Still, it doesn't matter because v10 has no
1194 delay slot for BREAK so it will not be executed). */
1195 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 16, 0x05b0);
1197 /* Modify registers to hold the right values for the sighandler
1198 context: updated stackpointer and return address pointing to
1199 the sigreturn stub. */
1200 bfd_putl32 (sp
, regbuf
);
1201 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1202 bfd_putl32 (sp
+ 8, regbuf
);
1203 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, TARGET_SRP_REGNUM
,
1206 current_cpu
->thread_data
[next
].sigdata
[sig
].pending
= 0;
1208 /* Block this signal (for the duration of the sighandler). */
1209 current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
= 1;
1211 sim_pc_set (current_cpu
, current_cpu
->sighandler
[sig
]);
1212 bfd_putl32 (sig
, regbuf
);
1213 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
,
1216 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1217 needed all this for, specifies a SA_SIGINFO call but treats it
1218 like an ordinary sighandler; only the signal number argument is
1219 inspected. To make future need to implement SA_SIGINFO
1220 correctly possible, we set the siginfo argument register to a
1221 magic (hopefully non-address) number. (NB: then, you should
1222 just need to pass the siginfo argument; it seems you probably
1223 don't need to implement the specific rt_sigreturn.) */
1224 bfd_putl32 (0xbad5161f, regbuf
);
1225 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R11
,
1228 /* The third argument is unused and the kernel sets it to 0. */
1229 bfd_putl32 (0, regbuf
);
1230 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R12
,
1235 /* No, there actually was no pending signal for this thread. Reset
1237 current_cpu
->thread_data
[next
].sigpending
= 0;
1241 /* Reschedule the simplest possible way until something else is absolutely
1243 - A. Find the next process (round-robin) that doesn't have at_syscall
1245 - B. If there is none, just run the next process, round-robin.
1246 - Clear at_syscall for the current process. */
1249 reschedule (SIM_CPU
*current_cpu
)
1251 SIM_DESC sd
= CPU_STATE (current_cpu
);
1254 /* Iterate over all thread slots, because after a few thread creations
1255 and exits, we don't know where the live ones are. */
1256 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1257 i
!= current_cpu
->threadno
;
1258 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1259 if (current_cpu
->thread_data
[i
].cpu_context
1260 && current_cpu
->thread_data
[i
].at_syscall
== 0)
1262 schedule (current_cpu
, i
);
1266 /* Pick any next live thread. */
1267 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1268 i
!= current_cpu
->threadno
;
1269 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1270 if (current_cpu
->thread_data
[i
].cpu_context
)
1272 schedule (current_cpu
, i
);
1276 /* More than one live thread, but we couldn't find the next one? */
1280 /* Set up everything to receive (or IGN) an incoming signal to the
1284 deliver_signal (SIM_CPU
*current_cpu
, int sig
, unsigned int pid
)
1287 USI pc
= sim_pc_get (current_cpu
);
1289 /* Find the thread index of the pid. */
1290 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
1291 /* Apparently it's ok to send signals to zombies (so a check for
1292 current_cpu->thread_data[i].cpu_context != NULL would be
1294 if (current_cpu
->thread_data
[i
].threadid
== pid
- TARGET_PID
)
1297 switch (current_cpu
->sighandler
[sig
])
1299 case TARGET_SIG_DFL
:
1302 /* The following according to the glibc
1303 documentation. (The kernel code has non-obvious
1304 execution paths.) */
1307 case TARGET_SIGSEGV
:
1309 case TARGET_SIGABRT
:
1310 case TARGET_SIGTRAP
:
1313 case TARGET_SIGTERM
:
1315 case TARGET_SIGQUIT
:
1316 case TARGET_SIGKILL
:
1319 case TARGET_SIGALRM
:
1320 case TARGET_SIGVTALRM
:
1321 case TARGET_SIGPROF
:
1322 case TARGET_SIGSTOP
:
1324 case TARGET_SIGPIPE
:
1325 case TARGET_SIGLOST
:
1326 case TARGET_SIGXCPU
:
1327 case TARGET_SIGXFSZ
:
1328 case TARGET_SIGUSR1
:
1329 case TARGET_SIGUSR2
:
1330 sim_io_eprintf (CPU_STATE (current_cpu
),
1331 "Exiting pid %d due to signal %d\n",
1333 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1334 NULL
, pc
, sim_stopped
,
1335 sig
== TARGET_SIGABRT
1336 ? SIM_SIGABRT
: SIM_SIGILL
);
1339 /* The default for all other signals is to be ignored. */
1344 case TARGET_SIG_IGN
:
1347 case TARGET_SIGKILL
:
1348 case TARGET_SIGSTOP
:
1349 /* Can't ignore these signals. */
1350 sim_io_eprintf (CPU_STATE (current_cpu
),
1351 "Exiting pid %d due to signal %d\n",
1353 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1354 NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1363 /* Mark the signal as pending, making schedule () check
1364 closer. The signal will be handled when the thread is
1365 scheduled and the signal is unblocked. */
1366 current_cpu
->thread_data
[i
].sigdata
[sig
].pending
= 1;
1367 current_cpu
->thread_data
[i
].sigpending
= 1;
1372 sim_io_eprintf (CPU_STATE (current_cpu
),
1373 "Unimplemented signal: %d\n", sig
);
1374 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
1375 sim_stopped
, SIM_SIGILL
);
1380 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu
)),
1384 /* Make the vector and the first item, the main thread. */
1387 make_first_thread (SIM_CPU
*current_cpu
)
1389 SIM_DESC sd
= CPU_STATE (current_cpu
);
1390 current_cpu
->thread_data
1392 SIM_TARGET_MAX_THREADS
1393 * sizeof (current_cpu
->thread_data
[0]));
1394 current_cpu
->thread_data
[0].cpu_context
1395 = (*current_cpu
->make_thread_cpu_data
) (current_cpu
,
1397 ->cpu_data_placeholder
);
1398 current_cpu
->thread_data
[0].parent_threadid
= -1;
1400 /* For good measure. */
1401 if (TARGET_SIG_DFL
!= 0)
1405 /* Handle unknown system calls. Returns (if it does) the syscall
1409 cris_unknown_syscall (SIM_CPU
*current_cpu
, USI pc
, char *s
, ...)
1411 SIM_DESC sd
= CPU_STATE (current_cpu
);
1412 host_callback
*cb
= STATE_CALLBACK (sd
);
1414 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
1415 || cris_unknown_syscall_action
== CRIS_USYSC_MSG_ENOSYS
)
1420 sim_io_evprintf (sd
, s
, ap
);
1423 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
)
1424 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1427 return -cb_host_to_target_errno (cb
, ENOSYS
);
1430 /* Main function: the handler of the "break 13" syscall insn. */
1433 cris_break_13_handler (SIM_CPU
*current_cpu
, USI callnum
, USI arg1
,
1434 USI arg2
, USI arg3
, USI arg4
, USI arg5
, USI arg6
,
1438 SIM_DESC sd
= CPU_STATE (current_cpu
);
1439 host_callback
*cb
= STATE_CALLBACK (sd
);
1441 int threadno
= current_cpu
->threadno
;
1443 current_cpu
->syscalls
++;
1445 CB_SYSCALL_INIT (&s
);
1451 /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need
1452 to sign-extend the lseek offset to be passed as a signed number,
1453 else we'll truncate it to something > 2GB on hosts where sizeof
1454 long > sizeof USI. We avoid doing it for all syscalls, as arg2 is
1455 e.g. an address for some syscalls. */
1456 if (callnum
== TARGET_SYS_lseek
)
1459 if (callnum
== TARGET_SYS_exit_group
1460 || (callnum
== TARGET_SYS_exit
&& current_cpu
->m1threads
== 0))
1462 if (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1463 & FLAG_CRIS_MISC_PROFILE_ALL
)
1464 dump_statistics (current_cpu
);
1465 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
1469 s
.p2
= (PTR
) current_cpu
;
1470 s
.read_mem
= sim_syscall_read_mem
;
1471 s
.write_mem
= sim_syscall_write_mem
;
1473 current_cpu_for_cb_callback
= current_cpu
;
1475 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1478 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
1480 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1483 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
1485 if (s
.errcode
!= 0 && s
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
1487 /* If the generic simulator call said ENOSYS, then let's try the
1488 ones we know ourselves.
1490 The convention is to provide *very limited* functionality on an
1491 as-needed basis, only what's covered by the test-suite, tests
1492 added when functionality changes and abort with a descriptive
1493 message for *everything* else. Where there's no test-case, we
1498 /* It's a pretty safe bet that the "old setup() system call"
1499 number will not be re-used; we can't say the same for higher
1500 numbers. We treat this simulator-generated call as "wait
1501 forever"; we re-run this insn. The wait is ended by a
1502 callback. Sanity check that this is the reason we got
1504 if (current_cpu
->thread_data
== NULL
1505 || (current_cpu
->thread_data
[threadno
].pipe_write_fd
== 0))
1506 goto unimplemented_syscall
;
1508 sim_pc_set (current_cpu
, pc
);
1512 case TARGET_SYS_fcntl64
:
1513 case TARGET_SYS_fcntl
:
1518 Glibc checks stdin, stdout and stderr fd:s for
1519 close-on-exec security sanity. We just need to provide a
1520 OK return value. If we really need to have a
1521 close-on-exec flag true, we could just do a real fcntl
1527 /* F_SETFD. Just ignore attempts to set the close-on-exec
1533 /* F_GETFL. Check for the special case for open+fdopen. */
1534 if (current_cpu
->last_syscall
== TARGET_SYS_open
1535 && arg1
== current_cpu
->last_open_fd
)
1537 retval
= current_cpu
->last_open_flags
& TARGET_O_ACCMODE
;
1542 /* Because we can't freopen fd:s 0, 1, 2 to mean
1543 something else than stdin, stdout and stderr
1544 (sim/common/syscall.c:cb_syscall special cases fd
1545 0, 1 and 2), we know what flags that we can
1546 sanely return for these fd:s. */
1547 retval
= TARGET_O_RDONLY
;
1550 else if (arg1
== 1 || arg1
== 2)
1552 retval
= TARGET_O_WRONLY
;
1557 /* Nothing else is implemented. */
1559 = cris_unknown_syscall (current_cpu
, pc
,
1560 "Unimplemented %s syscall "
1561 "(fd: 0x%lx: cmd: 0x%lx arg: "
1563 callnum
== TARGET_SYS_fcntl
1564 ? "fcntl" : "fcntl64",
1565 (unsigned long) (USI
) arg1
,
1566 (unsigned long) (USI
) arg2
,
1567 (unsigned long) (USI
) arg3
);
1572 case TARGET_SYS_uname
:
1574 /* Fill in a few constants to appease glibc. */
1575 static char sim_utsname
[6][65] =
1581 "cris", /* Overwritten below. */
1585 /* Having the hardware type in Linux equal to the bfd
1586 printable name is deliberate: if you make config.guess
1587 work on your Linux-type system the usual way, it
1588 probably will; either the bfd printable_name or the
1589 ambiguous arch_name. */
1590 strcpy (sim_utsname
[4], STATE_ARCHITECTURE (sd
)->printable_name
);
1592 if ((s
.write_mem
) (cb
, &s
, arg1
, (const char *) sim_utsname
,
1593 sizeof (sim_utsname
))
1594 != sizeof (sim_utsname
))
1595 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
1601 case TARGET_SYS_geteuid32
:
1602 /* We tell the truth with these. Maybe we shouldn't, but it
1603 should match the "stat" information. */
1604 retval
= geteuid ();
1607 case TARGET_SYS_getuid32
:
1611 case TARGET_SYS_getegid32
:
1612 retval
= getegid ();
1615 case TARGET_SYS_getgid32
:
1619 case TARGET_SYS_brk
:
1620 /* Most often, we just return the argument, like the Linux
1625 retval
= current_cpu
->endbrk
;
1626 else if (arg1
<= current_cpu
->endmem
)
1627 current_cpu
->endbrk
= arg1
;
1630 USI new_end
= (arg1
+ 8191) & ~8191;
1632 /* If the simulator wants to brk more than a certain very
1633 large amount, something is wrong. FIXME: Return an error
1634 or abort? Have command-line selectable? */
1635 if (new_end
- current_cpu
->endmem
> SIM_MAX_ALLOC_CHUNK
)
1637 current_cpu
->endbrk
= current_cpu
->endmem
;
1638 retval
= current_cpu
->endmem
;
1642 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1643 current_cpu
->endmem
,
1644 new_end
- current_cpu
->endmem
,
1646 current_cpu
->endbrk
= arg1
;
1647 current_cpu
->endmem
= new_end
;
1651 case TARGET_SYS_getpid
:
1652 /* Correct until CLONE_THREAD is implemented. */
1653 retval
= current_cpu
->thread_data
== NULL
1655 : TARGET_PID
+ current_cpu
->thread_data
[threadno
].threadid
;
1658 case TARGET_SYS_getppid
:
1659 /* Correct until CLONE_THREAD is implemented. */
1660 retval
= current_cpu
->thread_data
== NULL
1663 + current_cpu
->thread_data
[threadno
].parent_threadid
);
1666 case TARGET_SYS_mmap2
:
1675 /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1676 still masked away this bit, so let's just ignore
1678 flags
&= ~TARGET_MAP_DENYWRITE
;
1680 /* If the simulator wants to mmap more than the very large
1681 limit, something is wrong. FIXME: Return an error or
1682 abort? Have command-line selectable? */
1683 if (len
> SIM_MAX_ALLOC_CHUNK
)
1685 retval
= -cb_host_to_target_errno (cb
, ENOMEM
);
1689 if ((prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
)
1691 != (TARGET_PROT_READ
1693 | TARGET_PROT_EXEC
))
1694 && (prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
))
1695 && prot
!= TARGET_PROT_READ
)
1696 || (flags
!= (TARGET_MAP_ANONYMOUS
| TARGET_MAP_PRIVATE
)
1697 && flags
!= TARGET_MAP_PRIVATE
1698 && flags
!= (TARGET_MAP_ANONYMOUS
1699 | TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1700 && flags
!= (TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1701 && flags
!= TARGET_MAP_SHARED
)
1703 && prot
!= TARGET_PROT_READ
1704 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1705 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1706 || (fd
== (USI
) -1 && pgoff
!= 0)
1707 || (fd
!= (USI
) -1 && (flags
& TARGET_MAP_ANONYMOUS
)))
1710 = cris_unknown_syscall (current_cpu
, pc
,
1711 "Unimplemented mmap2 call "
1712 "(0x%lx, 0x%lx, 0x%lx, "
1713 "0x%lx, 0x%lx, 0x%lx)\n",
1714 (unsigned long) arg1
,
1715 (unsigned long) arg2
,
1716 (unsigned long) arg3
,
1717 (unsigned long) arg4
,
1718 (unsigned long) arg5
,
1719 (unsigned long) arg6
);
1722 else if (fd
!= (USI
) -1)
1729 /* A non-aligned argument is allowed for files. */
1730 USI newlen
= (len
+ 8191) & ~8191;
1732 /* We only support read, read|exec, and read|write,
1733 which we should already have checked. Check again
1735 if (prot
!= TARGET_PROT_READ
1736 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1737 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1740 if (flags
& TARGET_MAP_FIXED
)
1741 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1743 else if (is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1748 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1749 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1753 if (newaddr
>= (USI
) -8191)
1756 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1760 /* We were asked for MAP_FIXED, but couldn't. */
1761 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1764 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1766 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1770 /* Find the current position in the file. */
1771 s
.func
= TARGET_SYS_lseek
;
1775 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1782 /* Move to the correct offset in the file. */
1783 s
.func
= TARGET_SYS_lseek
;
1785 s
.arg2
= pgoff
*8192;
1787 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1793 /* Use the standard read callback to read in "len"
1795 s
.func
= TARGET_SYS_read
;
1799 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1802 /* If the result is a page or more lesser than what
1803 was requested, something went wrong. */
1804 if (len
>= 8192 && (USI
) s
.result
<= len
- 8192)
1807 /* After reading, we need to go back to the previous
1808 position in the file. */
1809 s
.func
= TARGET_SYS_lseek
;
1813 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1815 if (pos
!= (USI
) s
.result
)
1822 USI newlen
= (len
+ 8191) & ~8191;
1825 if (flags
& TARGET_MAP_FIXED
)
1826 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1828 else if (is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1832 newaddr
= create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1833 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1837 if (newaddr
>= (USI
) -8191)
1838 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1842 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1845 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1847 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1854 case TARGET_SYS_mprotect
:
1856 /* We only cover the case of linuxthreads mprotecting out
1857 its stack guard page and of dynamic loading mprotecting
1858 away the data (for some reason the whole library, then
1859 mprotects away the data part and mmap-FIX:es it again. */
1864 if (prot
!= TARGET_PROT_NONE
1865 || !is_mapped_only (sd
, ¤t_cpu
->highest_mmapped_page
,
1866 addr
, (len
+ 8191) & ~8191))
1869 = cris_unknown_syscall (current_cpu
, pc
,
1870 "Unimplemented mprotect call "
1871 "(0x%lx, 0x%lx, 0x%lx)\n",
1872 (unsigned long) arg1
,
1873 (unsigned long) arg2
,
1874 (unsigned long) arg3
);
1878 /* Just ignore this. We could make this equal to munmap,
1879 but then we'd have to make sure no anon mmaps gets this
1880 address before a subsequent MAP_FIXED mmap intended to
1886 case TARGET_SYS_ioctl
:
1888 /* We support only a very limited functionality: checking
1889 stdout with TCGETS to perform the isatty function. The
1890 TCGETS ioctl isn't actually performed or the result used by
1891 an isatty () caller in a "hello, world" program; only the
1892 return value is then used. Maybe we shouldn't care about
1893 the environment of the simulator regarding isatty, but
1894 that's been working before, in the xsim simulator. */
1895 if (arg2
== TARGET_TCGETS
&& arg1
== 1)
1896 retval
= isatty (1) ? 0 : cb_host_to_target_errno (cb
, EINVAL
);
1898 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1902 case TARGET_SYS_munmap
:
1907 = unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1909 retval
= result
!= 0 ? -cb_host_to_target_errno (cb
, result
) : 0;
1913 case TARGET_SYS_wait4
:
1921 /* FIXME: We're not properly implementing __WCLONE, and we
1922 don't really need the special casing so we might as well
1923 make this general. */
1924 if ((!(pid
== (USI
) -1
1925 && options
== (TARGET___WCLONE
| TARGET_WNOHANG
)
1928 && (options
== TARGET___WCLONE
1929 || options
== TARGET___WALL
)))
1931 || current_cpu
->thread_data
== NULL
)
1934 = cris_unknown_syscall (current_cpu
, pc
,
1935 "Unimplemented wait4 call "
1936 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1937 (unsigned long) arg1
,
1938 (unsigned long) arg2
,
1939 (unsigned long) arg3
,
1940 (unsigned long) arg4
);
1944 if (pid
== (USI
) -1)
1945 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1947 if (current_cpu
->thread_data
[threadno
].threadid
1948 == current_cpu
->thread_data
[i
].parent_threadid
1949 && current_cpu
->thread_data
[i
].threadid
!= 0
1950 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1952 /* A zombied child. Get the exit value and clear the
1953 zombied entry so it will be reused. */
1954 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, saddr
,
1956 ->thread_data
[i
].exitval
);
1958 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1959 memset (¤t_cpu
->thread_data
[i
], 0,
1960 sizeof (current_cpu
->thread_data
[i
]));
1966 /* We're waiting for a specific PID. If we don't find
1967 it zombied on this run, rerun the syscall. */
1968 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1969 if (pid
== current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
1970 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1973 /* Get the exit value if the caller wants it. */
1974 sim_core_write_unaligned_4 (current_cpu
, pc
, 0,
1981 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1982 memset (¤t_cpu
->thread_data
[i
], 0,
1983 sizeof (current_cpu
->thread_data
[i
]));
1988 sim_pc_set (current_cpu
, pc
);
1991 retval
= -cb_host_to_target_errno (cb
, ECHILD
);
1996 case TARGET_SYS_rt_sigaction
:
2004 __sighandler_t sa_handler;
2005 unsigned long sa_flags;
2006 void (*sa_restorer)(void);
2012 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, old_sa
+ 0,
2013 current_cpu
->sighandler
[signum
]);
2014 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 4, 0);
2015 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 8, 0);
2017 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
2018 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 12, 0);
2019 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 16, 0);
2023 USI target_sa_handler
2024 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
);
2026 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 4);
2027 USI target_sa_restorer
2028 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 8);
2029 USI target_sa_mask_low
2030 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 12);
2031 USI target_sa_mask_high
2032 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 16);
2034 /* We won't interrupt a syscall so we won't restart it,
2035 but a signal(2) call ends up syscalling rt_sigaction
2036 with this flag, so we have to handle it. The
2037 sa_restorer field contains garbage when not
2038 TARGET_SA_RESTORER, so don't look at it. For the
2039 time being, we don't nest sighandlers, so we
2040 ignore the sa_mask, which simplifies things. */
2041 if ((target_sa_flags
!= 0
2042 && target_sa_flags
!= TARGET_SA_RESTART
2043 && target_sa_flags
!= (TARGET_SA_RESTART
|TARGET_SA_SIGINFO
))
2044 || target_sa_handler
== 0)
2047 = cris_unknown_syscall (current_cpu
, pc
,
2048 "Unimplemented rt_sigaction "
2051 "[0x%x, 0x%x, 0x%x, "
2052 "{0x%x, 0x%x}], 0x%lx)\n",
2053 (unsigned long) arg1
,
2054 (unsigned long) arg2
,
2059 target_sa_mask_high
,
2060 (unsigned long) arg3
);
2064 current_cpu
->sighandler
[signum
] = target_sa_handler
;
2066 /* Because we may have unblocked signals, one may now be
2067 pending, if there are threads, that is. */
2068 if (current_cpu
->thread_data
)
2069 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2075 case TARGET_SYS_mremap
:
2081 USI new_addr
= arg5
;
2084 if (new_len
== old_len
)
2085 /* The program and/or library is possibly confused but
2086 this is a valid call. Happens with ipps-1.40 on file
2089 else if (new_len
< old_len
)
2091 /* Shrinking is easy. */
2092 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2093 addr
+ new_len
, old_len
- new_len
) != 0)
2094 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2098 else if (! is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
2099 addr
+ old_len
, new_len
- old_len
))
2101 /* If the extension isn't mapped, we can just add it. */
2103 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2104 addr
+ old_len
, new_len
- old_len
);
2106 if (mapped_addr
> (USI
) -8192)
2107 retval
= -cb_host_to_target_errno (cb
, -(SI
) mapped_addr
);
2111 else if (flags
& TARGET_MREMAP_MAYMOVE
)
2113 /* Create a whole new map and copy the contents
2114 block-by-block there. We ignore the new_addr argument
2117 USI prev_addr
= addr
;
2118 USI prev_len
= old_len
;
2121 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2124 if (mapped_addr
> (USI
) -8192)
2126 retval
= -cb_host_to_target_errno (cb
, -(SI
) new_addr
);
2130 retval
= mapped_addr
;
2133 old_len
-= 8192, mapped_addr
+= 8192, addr
+= 8192)
2135 if (sim_core_read_buffer (sd
, current_cpu
, read_map
, buf
,
2137 || sim_core_write_buffer (sd
, current_cpu
, 0, buf
,
2138 mapped_addr
, 8192) != 8192)
2142 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2143 prev_addr
, prev_len
) != 0)
2147 retval
= -cb_host_to_target_errno (cb
, -ENOMEM
);
2151 case TARGET_SYS_poll
:
2153 int npollfds
= arg2
;
2169 /* Check that this is the expected poll call from
2170 linuxthreads/manager.c; we don't support anything else.
2171 Remember, fd == 0 isn't supported. */
2173 || ((fd
= sim_core_read_unaligned_4 (current_cpu
, pc
,
2175 || ((events
= sim_core_read_unaligned_2 (current_cpu
, pc
,
2178 || ((cb
->to_fstat
) (cb
, fd
, &buf
) != 0
2179 || (buf
.st_mode
& S_IFIFO
) == 0)
2180 || current_cpu
->thread_data
== NULL
)
2183 = cris_unknown_syscall (current_cpu
, pc
,
2184 "Unimplemented poll syscall "
2185 "(0x%lx: [0x%x, 0x%x, x], "
2187 (unsigned long) arg1
, fd
, events
,
2188 (unsigned long) arg2
,
2189 (unsigned long) arg3
);
2195 /* Iterate over threads; find a marker that a writer is
2196 sleeping, waiting for a reader. */
2197 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2198 if (current_cpu
->thread_data
[i
].cpu_context
!= NULL
2199 && current_cpu
->thread_data
[i
].pipe_read_fd
== fd
)
2201 revents
= TARGET_POLLIN
;
2206 /* Timeout decreases with whatever time passed between the
2207 last syscall and this. That's not exactly right for the
2208 first call, but it's close enough that it isn't
2209 worthwhile to complicate matters by making that a special
2212 -= (TARGET_TIME_MS (current_cpu
)
2213 - (current_cpu
->thread_data
[threadno
].last_execution
));
2215 /* Arrange to repeat this syscall until timeout or event,
2216 decreasing timeout at each iteration. */
2217 if (timeout
> 0 && revents
== 0)
2219 bfd_byte timeout_buf
[4];
2221 bfd_putl32 (timeout
, timeout_buf
);
2222 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2223 H_GR_R12
, timeout_buf
, 4);
2224 sim_pc_set (current_cpu
, pc
);
2229 sim_core_write_unaligned_2 (current_cpu
, pc
, 0, ufds
+ 4 + 2,
2234 case TARGET_SYS_time
:
2236 retval
= (int) (*cb
->time
) (cb
, 0L);
2238 /* At time of this writing, CB_SYSCALL_time doesn't do the
2239 part of setting *arg1 to the return value. */
2241 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, retval
);
2245 case TARGET_SYS_gettimeofday
:
2248 USI ts
= TARGET_TIME (current_cpu
);
2249 USI tms
= TARGET_TIME_MS (current_cpu
);
2251 /* First dword is seconds since TARGET_EPOCH. */
2252 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, ts
);
2254 /* Second dword is microseconds. */
2255 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4,
2256 (tms
% 1000) * 1000);
2260 /* Time-zone info is always cleared. */
2261 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, 0);
2262 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, 0);
2267 case TARGET_SYS_llseek
:
2269 /* If it fits, tweak parameters to fit the "generic" 32-bit
2270 lseek and use that. */
2278 if (!((offs_hi
== 0 && offs_lo
>= 0)
2279 || (offs_hi
== -1 && offs_lo
< 0)))
2282 = cris_unknown_syscall (current_cpu
, pc
,
2283 "Unimplemented llseek offset,"
2284 " fd %d: 0x%x:0x%x\n",
2285 fd
, (unsigned) arg2
,
2290 s
.func
= TARGET_SYS_lseek
;
2293 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2295 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
2297 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2300 retval
= -s
.errcode
;
2303 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
,
2305 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
+ 4,
2306 s
.result
< 0 ? -1 : 0);
2311 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2314 void *iov_base; Starting address
2315 size_t iov_len; Number of bytes to transfer
2317 case TARGET_SYS_writev
:
2325 /* We'll ignore strict error-handling and just do multiple write calls. */
2326 for (i
= 0; i
< iovcnt
; i
++)
2330 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2333 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2336 s
.func
= TARGET_SYS_write
;
2341 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2343 sysret
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2345 if (sysret
!= iov_len
)
2360 /* This one does have a generic callback function, but at the time
2361 of this writing, cb_syscall does not have code for it, and we
2362 need target-specific code for the threads implementation
2364 case TARGET_SYS_kill
:
2371 /* At kill(2), glibc sets signal masks such that the thread
2372 machinery is initialized. Still, there is and was only
2374 if (current_cpu
->max_threadid
== 0)
2376 if (pid
!= TARGET_PID
)
2378 retval
= -cb_host_to_target_errno (cb
, EPERM
);
2382 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2383 if (sig
== TARGET_SIGABRT
)
2384 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2385 the end-point for failing GCC test-cases. */
2386 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2390 sim_io_eprintf (sd
, "Unimplemented signal: %d\n", sig
);
2391 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2395 /* This will not be reached. */
2399 retval
= deliver_signal (current_cpu
, sig
, pid
);
2403 case TARGET_SYS_rt_sigprocmask
:
2410 if (how
!= TARGET_SIG_BLOCK
2411 && how
!= TARGET_SIG_SETMASK
2412 && how
!= TARGET_SIG_UNBLOCK
)
2415 = cris_unknown_syscall (current_cpu
, pc
,
2416 "Unimplemented rt_sigprocmask "
2417 "syscall (0x%x, 0x%x, 0x%x)\n",
2425 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2428 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2431 /* The sigmask is kept in the per-thread data, so we may
2432 need to create the first one. */
2433 if (current_cpu
->thread_data
== NULL
)
2434 make_first_thread (current_cpu
);
2436 if (how
== TARGET_SIG_SETMASK
)
2437 for (i
= 0; i
< 64; i
++)
2438 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
= 0;
2440 for (i
= 0; i
< 32; i
++)
2441 if ((set_low
& (1 << i
)))
2442 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2443 = (how
!= TARGET_SIG_UNBLOCK
);
2445 for (i
= 0; i
< 31; i
++)
2446 if ((set_high
& (1 << i
)))
2447 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2448 = (how
!= TARGET_SIG_UNBLOCK
);
2450 /* The mask changed, so a signal may be unblocked for
2452 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2460 for (i
= 0; i
< 32; i
++)
2461 if (current_cpu
->thread_data
[threadno
]
2462 .sigdata
[i
+ 1].blocked
)
2464 for (i
= 0; i
< 31; i
++)
2465 if (current_cpu
->thread_data
[threadno
]
2466 .sigdata
[i
+ 33].blocked
)
2469 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 0, set_low
);
2470 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 4, set_high
);
2477 case TARGET_SYS_sigreturn
:
2481 int was_sigsuspended
;
2483 if (current_cpu
->thread_data
== NULL
2484 /* The CPU context is saved with the simulator data, not
2485 on the stack as in the real world. */
2486 || (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
2490 = cris_unknown_syscall (current_cpu
, pc
,
2491 "Invalid sigreturn syscall: "
2492 "no signal handler active "
2493 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2495 (unsigned long) arg1
,
2496 (unsigned long) arg2
,
2497 (unsigned long) arg3
,
2498 (unsigned long) arg4
,
2499 (unsigned long) arg5
,
2500 (unsigned long) arg6
);
2505 = current_cpu
->thread_data
[threadno
].sigsuspended
;
2507 /* Restore the sigmask, either from the stack copy made when
2508 the sighandler was called, or from the saved state
2509 specifically for sigsuspend(2). */
2510 if (was_sigsuspended
)
2512 current_cpu
->thread_data
[threadno
].sigsuspended
= 0;
2513 for (i
= 0; i
< 64; i
++)
2514 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
2515 = current_cpu
->thread_data
[threadno
]
2516 .sigdata
[i
].blocked_suspendsave
;
2524 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2525 H_GR_SP
, regbuf
, 4);
2526 sp
= bfd_getl32 (regbuf
);
2528 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
);
2530 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
+ 4);
2532 for (i
= 0; i
< 32; i
++)
2533 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2534 = (set_low
& (1 << i
)) != 0;
2535 for (i
= 0; i
< 31; i
++)
2536 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2537 = (set_high
& (1 << i
)) != 0;
2540 /* The mask changed, so a signal may be unblocked for
2542 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2544 memcpy (¤t_cpu
->cpu_data_placeholder
,
2545 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
,
2546 current_cpu
->thread_cpu_data_size
);
2547 free (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
);
2548 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
= NULL
;
2550 /* The return value must come from the saved R10. */
2551 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, regbuf
, 4);
2552 retval
= bfd_getl32 (regbuf
);
2554 /* We must also break the "sigsuspension loop". */
2555 if (was_sigsuspended
)
2556 sim_pc_set (current_cpu
, sim_pc_get (current_cpu
) + 2);
2560 case TARGET_SYS_rt_sigsuspend
:
2568 = cris_unknown_syscall (current_cpu
, pc
,
2569 "Unimplemented rt_sigsuspend syscall"
2570 " arguments (0x%lx, 0x%lx)\n",
2571 (unsigned long) arg1
,
2572 (unsigned long) arg2
);
2576 /* Don't change the signal mask if we're already in
2577 sigsuspend state (i.e. this syscall is a rerun). */
2578 else if (!current_cpu
->thread_data
[threadno
].sigsuspended
)
2581 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2584 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2588 /* Save the current sigmask and insert the user-supplied
2590 for (i
= 0; i
< 32; i
++)
2592 current_cpu
->thread_data
[threadno
]
2593 .sigdata
[i
+ 1].blocked_suspendsave
2594 = current_cpu
->thread_data
[threadno
]
2595 .sigdata
[i
+ 1].blocked
;
2597 current_cpu
->thread_data
[threadno
]
2598 .sigdata
[i
+ 1].blocked
= (set_low
& (1 << i
)) != 0;
2600 for (i
= 0; i
< 31; i
++)
2602 current_cpu
->thread_data
[threadno
]
2603 .sigdata
[i
+ 33].blocked_suspendsave
2604 = current_cpu
->thread_data
[threadno
]
2605 .sigdata
[i
+ 33].blocked
;
2606 current_cpu
->thread_data
[threadno
]
2607 .sigdata
[i
+ 33].blocked
= (set_high
& (1 << i
)) != 0;
2610 current_cpu
->thread_data
[threadno
].sigsuspended
= 1;
2612 /* The mask changed, so a signal may be unblocked for
2614 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2617 /* Because we don't use arg1 (newsetp) when this syscall is
2618 rerun, it doesn't matter that we overwrite it with the
2619 (constant) return value. */
2620 retval
= -cb_host_to_target_errno (cb
, EINTR
);
2621 sim_pc_set (current_cpu
, pc
);
2625 /* Add case labels here for other syscalls using the 32-bit
2626 "struct stat", provided they have a corresponding simulator
2627 function of course. */
2628 case TARGET_SYS_stat
:
2629 case TARGET_SYS_fstat
:
2631 /* As long as the infrastructure doesn't cache anything
2632 related to the stat mapping, this trick gets us a dual
2633 "struct stat"-type mapping in the least error-prone way. */
2634 const char *saved_map
= cb
->stat_map
;
2635 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
2637 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_stat32_map
;
2638 cb
->stat_map
= stat32_map
;
2640 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2643 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2646 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2648 cb
->stat_map
= saved_map
;
2649 cb
->syscall_map
= saved_syscall_map
;
2653 case TARGET_SYS_getcwd
:
2658 char *cwd
= xmalloc (SIM_PATHMAX
);
2659 if (cwd
!= getcwd (cwd
, SIM_PATHMAX
))
2662 /* FIXME: When and if we support chdir, we need something
2663 a bit more elaborate. */
2664 if (simulator_sysroot
[0] != '\0')
2667 retval
= -cb_host_to_target_errno (cb
, ERANGE
);
2668 if (strlen (cwd
) + 1 <= size
)
2670 retval
= strlen (cwd
) + 1;
2671 if (sim_core_write_buffer (sd
, current_cpu
, 0, cwd
,
2673 != (unsigned int) retval
)
2674 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2680 case TARGET_SYS_access
:
2684 char *pbuf
= xmalloc (SIM_PATHMAX
);
2689 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2691 strcpy (pbuf
, simulator_sysroot
);
2692 o
+= strlen (simulator_sysroot
);
2695 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2698 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2699 if (pbuf
[i
+ o
] == 0)
2703 if (i
+ o
== SIM_PATHMAX
)
2705 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2709 /* Assert that we don't get calls for files for which we
2710 don't have support. */
2711 if (strncmp (pbuf
+ strlen (simulator_sysroot
),
2714 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2721 if (access (pbuf
, hmode
) != 0)
2722 retval
= -cb_host_to_target_errno (cb
, errno
);
2730 case TARGET_SYS_readlink
:
2735 char *pbuf
= xmalloc (SIM_PATHMAX
);
2736 char *lbuf
= xmalloc (SIM_PATHMAX
);
2737 char *lbuf_alloc
= lbuf
;
2742 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2744 strcpy (pbuf
, simulator_sysroot
);
2745 o
+= strlen (simulator_sysroot
);
2748 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2751 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2752 if (pbuf
[i
+ o
] == 0)
2756 if (i
+ o
== SIM_PATHMAX
)
2758 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2762 /* Intervene calls for certain files expected in the target
2763 proc file system. */
2764 if (strcmp (pbuf
+ strlen (simulator_sysroot
),
2765 "/proc/" XSTRING (TARGET_PID
) "/exe") == 0)
2768 = (STATE_PROG_ARGV (sd
) != NULL
2769 ? *STATE_PROG_ARGV (sd
) : NULL
);
2771 if (argv0
== NULL
|| *argv0
== '.')
2774 = cris_unknown_syscall (current_cpu
, pc
,
2775 "Unimplemented readlink syscall "
2776 "(0x%lx: [\"%s\"], 0x%lx)\n",
2777 (unsigned long) arg1
, pbuf
,
2778 (unsigned long) arg2
);
2781 else if (*argv0
== '/')
2783 if (strncmp (simulator_sysroot
, argv0
,
2784 strlen (simulator_sysroot
)) == 0)
2785 argv0
+= strlen (simulator_sysroot
);
2787 strcpy (lbuf
, argv0
);
2788 nchars
= strlen (argv0
) + 1;
2792 if (getcwd (lbuf
, SIM_PATHMAX
) != NULL
2793 && strlen (lbuf
) + 2 + strlen (argv0
) < SIM_PATHMAX
)
2795 if (strncmp (simulator_sysroot
, lbuf
,
2796 strlen (simulator_sysroot
)) == 0)
2797 lbuf
+= strlen (simulator_sysroot
);
2800 strcat (lbuf
, argv0
);
2801 nchars
= strlen (lbuf
) + 1;
2808 nchars
= readlink (pbuf
, lbuf
, SIM_PATHMAX
);
2810 /* We trust that the readlink result returns a *relative*
2811 link, or one already adjusted for the file-path-prefix.
2812 (We can't generally tell the difference, so we go with
2813 the easiest decision; no adjustment.) */
2817 retval
= -cb_host_to_target_errno (cb
, errno
);
2821 if (bufsiz
< nchars
)
2824 if (sim_core_write_buffer (sd
, current_cpu
, write_map
, lbuf
,
2825 buf
, nchars
) != (unsigned int) nchars
)
2826 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2835 case TARGET_SYS_sched_getscheduler
:
2839 /* FIXME: Search (other) existing threads. */
2840 if (pid
!= 0 && pid
!= TARGET_PID
)
2841 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2843 retval
= TARGET_SCHED_OTHER
;
2847 case TARGET_SYS_sched_getparam
:
2853 struct sched_param {
2857 if (pid
!= 0 && pid
!= TARGET_PID
)
2858 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2861 /* FIXME: Save scheduler setting before threads are
2863 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, paramp
,
2864 current_cpu
->thread_data
!= NULL
2866 ->thread_data
[threadno
]
2874 case TARGET_SYS_sched_setparam
:
2879 if ((pid
!= 0 && pid
!= TARGET_PID
)
2880 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2882 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2888 case TARGET_SYS_sched_setscheduler
:
2894 if ((pid
!= 0 && pid
!= TARGET_PID
)
2895 || policy
!= TARGET_SCHED_OTHER
2896 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2898 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2900 /* FIXME: Save scheduler setting to be read in later
2901 sched_getparam calls. */
2906 case TARGET_SYS_sched_yield
:
2907 /* We reschedule to the next thread after a syscall anyway, so
2908 we don't have to do anything here than to set the return
2913 case TARGET_SYS_sched_get_priority_min
:
2914 case TARGET_SYS_sched_get_priority_max
:
2916 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2921 case TARGET_SYS_ugetrlimit
:
2923 unsigned int curlim
, maxlim
;
2924 if (arg1
!= TARGET_RLIMIT_STACK
&& arg1
!= TARGET_RLIMIT_NOFILE
)
2926 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2932 unsigned long rlim_cur;
2933 unsigned long rlim_max;
2935 if (arg1
== TARGET_RLIMIT_NOFILE
)
2937 /* Sadly a very low limit. Better not lie, though. */
2938 maxlim
= curlim
= MAX_CALLBACK_FDS
;
2940 else /* arg1 == TARGET_RLIMIT_STACK */
2942 maxlim
= 0xffffffff;
2945 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, curlim
);
2946 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, maxlim
);
2951 case TARGET_SYS_setrlimit
:
2952 if (arg1
!= TARGET_RLIMIT_STACK
)
2954 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2957 /* FIXME: Save values for future ugetrlimit calls. */
2961 /* Provide a very limited subset of the sysctl functions, and
2962 abort for the rest. */
2963 case TARGET_SYS__sysctl
:
2966 struct __sysctl_args {
2973 unsigned long __unused[4];
2975 SI name
= sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
);
2976 SI name0
= name
== 0
2977 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
);
2978 SI name1
= name
== 0
2979 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
+ 4);
2981 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4);
2983 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 8);
2985 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 12);
2986 SI oldlen
= oldlenp
== 0
2987 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, oldlenp
);
2989 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 16);
2991 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 20);
2993 if (name0
== TARGET_CTL_KERN
&& name1
== TARGET_CTL_KERN_VERSION
)
2995 SI to_write
= oldlen
< (SI
) sizeof (TARGET_UTSNAME
)
2996 ? oldlen
: (SI
) sizeof (TARGET_UTSNAME
);
2998 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldlenp
,
2999 sizeof (TARGET_UTSNAME
));
3001 if (sim_core_write_buffer (sd
, current_cpu
, write_map
,
3002 TARGET_UTSNAME
, oldval
,
3004 != (unsigned int) to_write
)
3005 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
3012 = cris_unknown_syscall (current_cpu
, pc
,
3013 "Unimplemented _sysctl syscall "
3014 "(0x%lx: [0x%lx, 0x%lx],"
3015 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
3016 (unsigned long) name
,
3017 (unsigned long) name0
,
3018 (unsigned long) name1
,
3019 (unsigned long) nlen
,
3020 (unsigned long) oldval
,
3021 (unsigned long) oldlenp
,
3022 (unsigned long) newval
,
3023 (unsigned long) newlen
);
3027 case TARGET_SYS_exit
:
3029 /* Here for all but the last thread. */
3032 = current_cpu
->thread_data
[threadno
].threadid
+ TARGET_PID
;
3034 = (current_cpu
->thread_data
[threadno
].parent_threadid
3036 int exitsig
= current_cpu
->thread_data
[threadno
].exitsig
;
3038 /* Any children are now all orphans. */
3039 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3040 if (current_cpu
->thread_data
[i
].parent_threadid
3041 == current_cpu
->thread_data
[threadno
].threadid
)
3042 /* Make getppid(2) return 1 for them, poor little ones. */
3043 current_cpu
->thread_data
[i
].parent_threadid
= -TARGET_PID
+ 1;
3045 /* Free the cpu context data. When the parent has received
3046 the exit status, we'll clear the entry too. */
3047 free (current_cpu
->thread_data
[threadno
].cpu_context
);
3048 current_cpu
->thread_data
[threadno
].cpu_context
= NULL
;
3049 current_cpu
->m1threads
--;
3052 sim_io_eprintf (sd
, "Thread %d exited with status %d\n",
3054 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
3058 /* Still, we may want to support non-zero exit values. */
3059 current_cpu
->thread_data
[threadno
].exitval
= arg1
<< 8;
3062 deliver_signal (current_cpu
, exitsig
, ppid
);
3066 case TARGET_SYS_clone
:
3068 int nthreads
= current_cpu
->m1threads
+ 1;
3069 void *thread_cpu_data
;
3070 bfd_byte old_sp_buf
[4];
3072 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3075 /* That's right, the syscall clone arguments are reversed
3076 compared to sys_clone notes in clone(2) and compared to
3077 other Linux ports (i.e. it's the same order as in the
3078 clone(2) libcall). */
3082 if (nthreads
== SIM_TARGET_MAX_THREADS
)
3084 retval
= -cb_host_to_target_errno (cb
, EAGAIN
);
3088 /* FIXME: Implement the low byte. */
3089 if ((flags
& ~TARGET_CSIGNAL
) !=
3092 | TARGET_CLONE_FILES
3093 | TARGET_CLONE_SIGHAND
)
3097 = cris_unknown_syscall (current_cpu
, pc
,
3098 "Unimplemented clone syscall "
3100 (unsigned long) arg1
,
3101 (unsigned long) arg2
);
3105 if (current_cpu
->thread_data
== NULL
)
3106 make_first_thread (current_cpu
);
3108 /* The created thread will get the new SP and a cleared R10.
3109 Since it's created out of a copy of the old thread and we
3110 don't have a set-register-function that just take the
3111 cpu_data as a parameter, we set the childs values first,
3112 and write back or overwrite them in the parent after the
3114 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
3115 H_GR_SP
, old_sp_buf
, 4);
3116 bfd_putl32 (newsp
, sp_buf
);
3117 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3118 H_GR_SP
, sp_buf
, 4);
3119 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3120 H_GR_R10
, (bfd_byte
*) zeros
, 4);
3123 ->make_thread_cpu_data
) (current_cpu
,
3124 ¤t_cpu
->cpu_data_placeholder
);
3125 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3126 H_GR_SP
, old_sp_buf
, 4);
3128 retval
= ++current_cpu
->max_threadid
+ TARGET_PID
;
3130 /* Find an unused slot. After a few threads have been created
3131 and exited, the array is expected to be a bit fragmented.
3132 We don't reuse the first entry, though, that of the
3134 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
3135 if (current_cpu
->thread_data
[i
].cpu_context
== NULL
3136 /* Don't reuse a zombied entry. */
3137 && current_cpu
->thread_data
[i
].threadid
== 0)
3140 memcpy (¤t_cpu
->thread_data
[i
],
3141 ¤t_cpu
->thread_data
[threadno
],
3142 sizeof (current_cpu
->thread_data
[i
]));
3143 current_cpu
->thread_data
[i
].cpu_context
= thread_cpu_data
;
3144 current_cpu
->thread_data
[i
].cpu_context_atsignal
= NULL
;
3145 current_cpu
->thread_data
[i
].threadid
= current_cpu
->max_threadid
;
3146 current_cpu
->thread_data
[i
].parent_threadid
3147 = current_cpu
->thread_data
[threadno
].threadid
;
3148 current_cpu
->thread_data
[i
].pipe_read_fd
= 0;
3149 current_cpu
->thread_data
[i
].pipe_write_fd
= 0;
3150 current_cpu
->thread_data
[i
].at_syscall
= 0;
3151 current_cpu
->thread_data
[i
].sigpending
= 0;
3152 current_cpu
->thread_data
[i
].sigsuspended
= 0;
3153 current_cpu
->thread_data
[i
].exitsig
= flags
& TARGET_CSIGNAL
;
3154 current_cpu
->m1threads
= nthreads
;
3158 /* Better watch these in case they do something necessary. */
3159 case TARGET_SYS_socketcall
:
3160 retval
= -cb_host_to_target_errno (cb
, ENOSYS
);
3163 case TARGET_SYS_set_thread_area
:
3164 /* Do the same error check as Linux. */
3167 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
3170 (*current_cpu
->set_target_thread_data
) (current_cpu
, arg1
);
3174 unimplemented_syscall
:
3177 = cris_unknown_syscall (current_cpu
, pc
,
3178 "Unimplemented syscall: %d "
3179 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3180 callnum
, arg1
, arg2
, arg3
, arg4
, arg5
,
3185 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
3186 if (callnum
== TARGET_SYS_open
)
3188 current_cpu
->last_open_fd
= retval
;
3189 current_cpu
->last_open_flags
= arg2
;
3192 current_cpu
->last_syscall
= callnum
;
3194 /* A system call is a rescheduling point. For the time being, we don't
3195 reschedule anywhere else. */
3196 if (current_cpu
->m1threads
!= 0
3197 /* We need to schedule off from an exiting thread that is the
3199 || (current_cpu
->thread_data
!= NULL
3200 && current_cpu
->thread_data
[threadno
].cpu_context
== NULL
))
3202 bfd_byte retval_buf
[4];
3204 current_cpu
->thread_data
[threadno
].last_execution
3205 = TARGET_TIME_MS (current_cpu
);
3206 bfd_putl32 (retval
, retval_buf
);
3207 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3209 current_cpu
->thread_data
[threadno
].at_syscall
= 1;
3210 reschedule (current_cpu
);
3212 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3213 retval
= bfd_getl32 (retval_buf
);
3219 /* Callback from simulator write saying that the pipe at (reader, writer)
3220 is now non-empty (so the writer should wait until the pipe is empty, at
3221 least not write to this or any other pipe). Simplest is to just wait
3222 until the pipe is empty. */
3225 cris_pipe_nonempty (host_callback
*cb ATTRIBUTE_UNUSED
,
3226 int reader
, int writer
)
3228 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3229 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3231 /* It's the current thread: we just have to re-run the current
3232 syscall instruction (presumably "break 13") and change the syscall
3233 to the special simulator-wait code. Oh, and set a marker that
3234 we're waiting, so we can disambiguate the special call from a
3237 This function may be called multiple times between cris_pipe_empty,
3238 but we must avoid e.g. decreasing PC every time. Check fd markers
3240 if (cpu
->thread_data
== NULL
)
3242 sim_io_eprintf (CPU_STATE (cpu
),
3243 "Terminating simulation due to writing pipe rd:wr %d:%d"
3244 " from one single thread\n", reader
, writer
);
3245 sim_engine_halt (CPU_STATE (cpu
), cpu
,
3246 NULL
, sim_pc_get (cpu
), sim_stopped
, SIM_SIGILL
);
3248 else if (cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
== 0)
3250 cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
= writer
;
3251 cpu
->thread_data
[cpu
->threadno
].pipe_read_fd
= reader
;
3252 /* FIXME: We really shouldn't change registers other than R10 in
3253 syscalls (like R9), here or elsewhere. */
3254 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R9
, (bfd_byte
*) zeros
, 4);
3255 sim_pc_set (cpu
, sim_pc_get (cpu
) - 2);
3259 /* Callback from simulator close or read call saying that the pipe at
3260 (reader, writer) is now empty (so the writer can write again, perhaps
3261 leave a waiting state). If there are bytes remaining, they couldn't be
3262 consumed (perhaps due to the pipe closing). */
3265 cris_pipe_empty (host_callback
*cb
,
3270 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3271 SIM_DESC sd
= CPU_STATE (current_cpu_for_cb_callback
);
3272 bfd_byte r10_buf
[4];
3274 = cb
->pipe_buffer
[writer
].size
- cb
->pipe_buffer
[reader
].size
;
3276 /* We need to find the thread that waits for this pipe. */
3277 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3278 if (cpu
->thread_data
[i
].cpu_context
3279 && cpu
->thread_data
[i
].pipe_write_fd
== writer
)
3283 /* Temporarily switch to this cpu context, so we can change the
3284 PC by ordinary calls. */
3286 memcpy (cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3287 &cpu
->cpu_data_placeholder
,
3288 cpu
->thread_cpu_data_size
);
3289 memcpy (&cpu
->cpu_data_placeholder
,
3290 cpu
->thread_data
[i
].cpu_context
,
3291 cpu
->thread_cpu_data_size
);
3293 /* The return value is supposed to contain the number of
3294 written bytes, which is the number of bytes requested and
3295 returned at the write call. You might think the right
3296 thing is to adjust the return-value to be only the
3297 *consumed* number of bytes, but it isn't. We're only
3298 called if the pipe buffer is fully consumed or it is being
3299 closed, possibly with remaining bytes. For the latter
3300 case, the writer is still supposed to see success for
3301 PIPE_BUF bytes (a constant which we happen to know and is
3302 unlikely to change). The return value may also be a
3303 negative number; an error value. This case is covered
3304 because "remaining" is always >= 0. */
3305 (*CPU_REG_FETCH (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3306 retval
= (int) bfd_getl_signed_32 (r10_buf
);
3307 if (retval
- remaining
> TARGET_PIPE_BUF
)
3309 bfd_putl32 (retval
- remaining
, r10_buf
);
3310 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3312 sim_pc_set (cpu
, sim_pc_get (cpu
) + 2);
3313 memcpy (cpu
->thread_data
[i
].cpu_context
,
3314 &cpu
->cpu_data_placeholder
,
3315 cpu
->thread_cpu_data_size
);
3316 memcpy (&cpu
->cpu_data_placeholder
,
3317 cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3318 cpu
->thread_cpu_data_size
);
3319 cpu
->thread_data
[i
].pipe_read_fd
= 0;
3320 cpu
->thread_data
[i
].pipe_write_fd
= 0;
3327 /* We have a simulator-specific notion of time. See TARGET_TIME. */
3330 cris_time (host_callback
*cb ATTRIBUTE_UNUSED
, long *t
)
3332 long retval
= TARGET_TIME (current_cpu_for_cb_callback
);
3338 /* Set target-specific callback data. */
3341 cris_set_callbacks (host_callback
*cb
)
3343 /* Yeargh, have to cast away constness to avoid warnings. */
3344 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_map
;
3345 cb
->errno_map
= (CB_TARGET_DEFS_MAP
*) errno_map
;
3347 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3348 parameter to cb_store_target_endian will make st_size negative.
3349 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3350 *unsigned*, and/or add syntax for signed-ness. */
3351 cb
->stat_map
= stat_map
;
3352 cb
->open_map
= (CB_TARGET_DEFS_MAP
*) open_map
;
3353 cb
->pipe_nonempty
= cris_pipe_nonempty
;
3354 cb
->pipe_empty
= cris_pipe_empty
;
3355 cb
->time
= cris_time
;
3358 /* Process an address exception. */
3361 cris_core_signal (SIM_DESC sd
, SIM_CPU
*current_cpu
, sim_cia cia
,
3362 unsigned int map
, int nr_bytes
, address_word addr
,
3363 transfer_type transfer
, sim_core_signals sig
)
3365 sim_core_signal (sd
, current_cpu
, cia
, map
, nr_bytes
, addr
,