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. */
35 #ifdef HAVE_SYS_PARAM_H
36 #include <sys/param.h>
38 #ifdef HAVE_SYS_STAT_H
41 /* For PATH_MAX, originally. */
46 /* From ld/sysdep.h. */
48 # define SIM_PATHMAX PATH_MAX
51 # define SIM_PATHMAX MAXPATHLEN
53 # define SIM_PATHMAX 1024
57 /* The verbatim values are from asm-cris/unistd.h. */
59 #define TARGET_SYS_exit 1
60 #define TARGET_SYS_read 3
61 #define TARGET_SYS_write 4
62 #define TARGET_SYS_open 5
63 #define TARGET_SYS_close 6
64 #define TARGET_SYS_unlink 10
65 #define TARGET_SYS_time 13
66 #define TARGET_SYS_lseek 19
67 #define TARGET_SYS_getpid 20
68 #define TARGET_SYS_access 33
69 #define TARGET_SYS_kill 37
70 #define TARGET_SYS_rename 38
71 #define TARGET_SYS_pipe 42
72 #define TARGET_SYS_brk 45
73 #define TARGET_SYS_ioctl 54
74 #define TARGET_SYS_fcntl 55
75 #define TARGET_SYS_getppid 64
76 #define TARGET_SYS_setrlimit 75
77 #define TARGET_SYS_gettimeofday 78
78 #define TARGET_SYS_readlink 85
79 #define TARGET_SYS_munmap 91
80 #define TARGET_SYS_truncate 92
81 #define TARGET_SYS_ftruncate 93
82 #define TARGET_SYS_socketcall 102
83 #define TARGET_SYS_stat 106
84 #define TARGET_SYS_fstat 108
85 #define TARGET_SYS_wait4 114
86 #define TARGET_SYS_sigreturn 119
87 #define TARGET_SYS_clone 120
88 #define TARGET_SYS_uname 122
89 #define TARGET_SYS_mprotect 125
90 #define TARGET_SYS_llseek 140
91 #define TARGET_SYS_writev 146
92 #define TARGET_SYS__sysctl 149
93 #define TARGET_SYS_sched_setparam 154
94 #define TARGET_SYS_sched_getparam 155
95 #define TARGET_SYS_sched_setscheduler 156
96 #define TARGET_SYS_sched_getscheduler 157
97 #define TARGET_SYS_sched_yield 158
98 #define TARGET_SYS_sched_get_priority_max 159
99 #define TARGET_SYS_sched_get_priority_min 160
100 #define TARGET_SYS_mremap 163
101 #define TARGET_SYS_poll 168
102 #define TARGET_SYS_rt_sigaction 174
103 #define TARGET_SYS_rt_sigprocmask 175
104 #define TARGET_SYS_rt_sigsuspend 179
105 #define TARGET_SYS_getcwd 183
106 #define TARGET_SYS_ugetrlimit 191
107 #define TARGET_SYS_mmap2 192
108 #define TARGET_SYS_stat64 195
109 #define TARGET_SYS_lstat64 196
110 #define TARGET_SYS_fstat64 197
111 #define TARGET_SYS_geteuid32 201
112 #define TARGET_SYS_getuid32 199
113 #define TARGET_SYS_getegid32 202
114 #define TARGET_SYS_getgid32 200
115 #define TARGET_SYS_fcntl64 221
116 #define TARGET_SYS_set_thread_area 243
117 #define TARGET_SYS_exit_group 252
119 #define TARGET_PROT_READ 0x1
120 #define TARGET_PROT_WRITE 0x2
121 #define TARGET_PROT_EXEC 0x4
122 #define TARGET_PROT_NONE 0x0
124 #define TARGET_MAP_SHARED 0x01
125 #define TARGET_MAP_PRIVATE 0x02
126 #define TARGET_MAP_TYPE 0x0f
127 #define TARGET_MAP_FIXED 0x10
128 #define TARGET_MAP_ANONYMOUS 0x20
129 #define TARGET_MAP_DENYWRITE 0x800
131 #define TARGET_CTL_KERN 1
132 #define TARGET_CTL_VM 2
133 #define TARGET_CTL_NET 3
134 #define TARGET_CTL_PROC 4
135 #define TARGET_CTL_FS 5
136 #define TARGET_CTL_DEBUG 6
137 #define TARGET_CTL_DEV 7
138 #define TARGET_CTL_BUS 8
139 #define TARGET_CTL_ABI 9
141 #define TARGET_CTL_KERN_VERSION 4
144 #define TARGET_MREMAP_MAYMOVE 1
145 #define TARGET_MREMAP_FIXED 2
147 #define TARGET_TCGETS 0x5401
149 #define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
151 /* Seconds since 1970-01-01 to the above date + 10 minutes;
152 'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'. */
153 #define TARGET_EPOCH 1230764410
155 /* Milliseconds since start of run. We use the number of syscalls to
156 avoid introducing noise in the execution time. */
157 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
159 /* Seconds as in time(2). */
160 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
162 #define TARGET_SCHED_OTHER 0
164 #define TARGET_RLIMIT_STACK 3
165 #define TARGET_RLIMIT_NOFILE 7
167 #define SIM_TARGET_MAX_THREADS 64
168 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
170 /* From linux/sched.h. */
171 #define TARGET_CSIGNAL 0x000000ff
172 #define TARGET_CLONE_VM 0x00000100
173 #define TARGET_CLONE_FS 0x00000200
174 #define TARGET_CLONE_FILES 0x00000400
175 #define TARGET_CLONE_SIGHAND 0x00000800
176 #define TARGET_CLONE_PID 0x00001000
177 #define TARGET_CLONE_PTRACE 0x00002000
178 #define TARGET_CLONE_VFORK 0x00004000
179 #define TARGET_CLONE_PARENT 0x00008000
180 #define TARGET_CLONE_THREAD 0x00010000
181 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
183 /* From asm-cris/poll.h. */
184 #define TARGET_POLLIN 1
186 /* From asm-cris/signal.h. */
187 #define TARGET_SIG_BLOCK 0
188 #define TARGET_SIG_UNBLOCK 1
189 #define TARGET_SIG_SETMASK 2
191 #define TARGET_SIG_DFL 0
192 #define TARGET_SIG_IGN 1
193 #define TARGET_SIG_ERR ((USI)-1)
195 #define TARGET_SIGHUP 1
196 #define TARGET_SIGINT 2
197 #define TARGET_SIGQUIT 3
198 #define TARGET_SIGILL 4
199 #define TARGET_SIGTRAP 5
200 #define TARGET_SIGABRT 6
201 #define TARGET_SIGIOT 6
202 #define TARGET_SIGBUS 7
203 #define TARGET_SIGFPE 8
204 #define TARGET_SIGKILL 9
205 #define TARGET_SIGUSR1 10
206 #define TARGET_SIGSEGV 11
207 #define TARGET_SIGUSR2 12
208 #define TARGET_SIGPIPE 13
209 #define TARGET_SIGALRM 14
210 #define TARGET_SIGTERM 15
211 #define TARGET_SIGSTKFLT 16
212 #define TARGET_SIGCHLD 17
213 #define TARGET_SIGCONT 18
214 #define TARGET_SIGSTOP 19
215 #define TARGET_SIGTSTP 20
216 #define TARGET_SIGTTIN 21
217 #define TARGET_SIGTTOU 22
218 #define TARGET_SIGURG 23
219 #define TARGET_SIGXCPU 24
220 #define TARGET_SIGXFSZ 25
221 #define TARGET_SIGVTALRM 26
222 #define TARGET_SIGPROF 27
223 #define TARGET_SIGWINCH 28
224 #define TARGET_SIGIO 29
225 #define TARGET_SIGPOLL SIGIO
226 /* Actually commented out in the kernel header. */
227 #define TARGET_SIGLOST 29
228 #define TARGET_SIGPWR 30
229 #define TARGET_SIGSYS 31
231 /* From include/asm-cris/signal.h. */
232 #define TARGET_SA_NOCLDSTOP 0x00000001
233 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
234 #define TARGET_SA_SIGINFO 0x00000004
235 #define TARGET_SA_ONSTACK 0x08000000
236 #define TARGET_SA_RESTART 0x10000000
237 #define TARGET_SA_NODEFER 0x40000000
238 #define TARGET_SA_RESETHAND 0x80000000
239 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
240 #define TARGET_SA_RESTORER 0x04000000
242 /* From linux/wait.h. */
243 #define TARGET_WNOHANG 1
244 #define TARGET_WUNTRACED 2
245 #define TARGET___WNOTHREAD 0x20000000
246 #define TARGET___WALL 0x40000000
247 #define TARGET___WCLONE 0x80000000
249 /* From linux/limits.h. */
250 #define TARGET_PIPE_BUF 4096
253 #define TARGET_R_OK 4
254 #define TARGET_W_OK 2
255 #define TARGET_X_OK 1
256 #define TARGET_F_OK 0
258 static const char stat_map
[] =
259 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
260 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
261 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
264 static const CB_TARGET_DEFS_MAP syscall_map
[] =
266 { "open", CB_SYS_open
, TARGET_SYS_open
},
267 { "close", CB_SYS_close
, TARGET_SYS_close
},
268 { "read", CB_SYS_read
, TARGET_SYS_read
},
269 { "write", CB_SYS_write
, TARGET_SYS_write
},
270 { "lseek", CB_SYS_lseek
, TARGET_SYS_lseek
},
271 { "unlink", CB_SYS_unlink
, TARGET_SYS_unlink
},
272 { "getpid", CB_SYS_getpid
, TARGET_SYS_getpid
},
273 { "fstat", CB_SYS_fstat
, TARGET_SYS_fstat64
},
274 { "lstat", CB_SYS_lstat
, TARGET_SYS_lstat64
},
275 { "stat", CB_SYS_stat
, TARGET_SYS_stat64
},
276 { "pipe", CB_SYS_pipe
, TARGET_SYS_pipe
},
277 { "rename", CB_SYS_rename
, TARGET_SYS_rename
},
278 { "truncate", CB_SYS_truncate
, TARGET_SYS_truncate
},
279 { "ftruncate", CB_SYS_ftruncate
, TARGET_SYS_ftruncate
},
283 /* An older, 32-bit-only stat mapping. */
284 static const char stat32_map
[] =
285 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
286 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
287 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
289 /* Map for calls using the 32-bit struct stat. Primarily used by the
290 newlib Linux mapping. */
291 static const CB_TARGET_DEFS_MAP syscall_stat32_map
[] =
293 { "fstat", CB_SYS_fstat
, TARGET_SYS_fstat
},
294 { "stat", CB_SYS_stat
, TARGET_SYS_stat
},
298 /* Giving the true value for the running sim process will lead to
299 non-time-invariant behavior. */
300 #define TARGET_PID 42
302 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
303 we did, we'd still don't get a register number with the "16" offset. */
304 #define TARGET_SRP_REGNUM (16+11)
306 /* Extracted by applying
307 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
308 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
309 adjusting the synonyms. */
311 static const CB_TARGET_DEFS_MAP errno_map
[] =
314 { "EPERM", EPERM
, 1 },
317 { "ENOENT", ENOENT
, 2 },
320 { "ESRCH", ESRCH
, 3 },
323 { "EINTR", EINTR
, 4 },
329 { "ENXIO", ENXIO
, 6 },
332 { "E2BIG", E2BIG
, 7 },
335 { "ENOEXEC", ENOEXEC
, 8 },
338 { "EBADF", EBADF
, 9 },
341 { "ECHILD", ECHILD
, 10 },
344 { "EAGAIN", EAGAIN
, 11 },
347 { "ENOMEM", ENOMEM
, 12 },
350 { "EACCES", EACCES
, 13 },
353 { "EFAULT", EFAULT
, 14 },
356 { "ENOTBLK", ENOTBLK
, 15 },
359 { "EBUSY", EBUSY
, 16 },
362 { "EEXIST", EEXIST
, 17 },
365 { "EXDEV", EXDEV
, 18 },
368 { "ENODEV", ENODEV
, 19 },
371 { "ENOTDIR", ENOTDIR
, 20 },
374 { "EISDIR", EISDIR
, 21 },
377 { "EINVAL", EINVAL
, 22 },
380 { "ENFILE", ENFILE
, 23 },
383 { "EMFILE", EMFILE
, 24 },
386 { "ENOTTY", ENOTTY
, 25 },
389 { "ETXTBSY", ETXTBSY
, 26 },
392 { "EFBIG", EFBIG
, 27 },
395 { "ENOSPC", ENOSPC
, 28 },
398 { "ESPIPE", ESPIPE
, 29 },
401 { "EROFS", EROFS
, 30 },
404 { "EMLINK", EMLINK
, 31 },
407 { "EPIPE", EPIPE
, 32 },
410 { "EDOM", EDOM
, 33 },
413 { "ERANGE", ERANGE
, 34 },
416 { "EDEADLK", EDEADLK
, 35 },
419 { "ENAMETOOLONG", ENAMETOOLONG
, 36 },
422 { "ENOLCK", ENOLCK
, 37 },
425 { "ENOSYS", ENOSYS
, 38 },
428 { "ENOTEMPTY", ENOTEMPTY
, 39 },
431 { "ELOOP", ELOOP
, 40 },
434 { "EWOULDBLOCK", EWOULDBLOCK
, 11 },
437 { "ENOMSG", ENOMSG
, 42 },
440 { "EIDRM", EIDRM
, 43 },
443 { "ECHRNG", ECHRNG
, 44 },
446 { "EL2NSYNC", EL2NSYNC
, 45 },
449 { "EL3HLT", EL3HLT
, 46 },
452 { "EL3RST", EL3RST
, 47 },
455 { "ELNRNG", ELNRNG
, 48 },
458 { "EUNATCH", EUNATCH
, 49 },
461 { "ENOCSI", ENOCSI
, 50 },
464 { "EL2HLT", EL2HLT
, 51 },
467 { "EBADE", EBADE
, 52 },
470 { "EBADR", EBADR
, 53 },
473 { "EXFULL", EXFULL
, 54 },
476 { "ENOANO", ENOANO
, 55 },
479 { "EBADRQC", EBADRQC
, 56 },
482 { "EBADSLT", EBADSLT
, 57 },
485 { "EDEADLOCK", EDEADLOCK
, 35 },
488 { "EBFONT", EBFONT
, 59 },
491 { "ENOSTR", ENOSTR
, 60 },
494 { "ENODATA", ENODATA
, 61 },
497 { "ETIME", ETIME
, 62 },
500 { "ENOSR", ENOSR
, 63 },
503 { "ENONET", ENONET
, 64 },
506 { "ENOPKG", ENOPKG
, 65 },
509 { "EREMOTE", EREMOTE
, 66 },
512 { "ENOLINK", ENOLINK
, 67 },
515 { "EADV", EADV
, 68 },
518 { "ESRMNT", ESRMNT
, 69 },
521 { "ECOMM", ECOMM
, 70 },
524 { "EPROTO", EPROTO
, 71 },
527 { "EMULTIHOP", EMULTIHOP
, 72 },
530 { "EDOTDOT", EDOTDOT
, 73 },
533 { "EBADMSG", EBADMSG
, 74 },
536 { "EOVERFLOW", EOVERFLOW
, 75 },
539 { "ENOTUNIQ", ENOTUNIQ
, 76 },
542 { "EBADFD", EBADFD
, 77 },
545 { "EREMCHG", EREMCHG
, 78 },
548 { "ELIBACC", ELIBACC
, 79 },
551 { "ELIBBAD", ELIBBAD
, 80 },
554 { "ELIBSCN", ELIBSCN
, 81 },
557 { "ELIBMAX", ELIBMAX
, 82 },
560 { "ELIBEXEC", ELIBEXEC
, 83 },
563 { "EILSEQ", EILSEQ
, 84 },
566 { "ERESTART", ERESTART
, 85 },
569 { "ESTRPIPE", ESTRPIPE
, 86 },
572 { "EUSERS", EUSERS
, 87 },
575 { "ENOTSOCK", ENOTSOCK
, 88 },
578 { "EDESTADDRREQ", EDESTADDRREQ
, 89 },
581 { "EMSGSIZE", EMSGSIZE
, 90 },
584 { "EPROTOTYPE", EPROTOTYPE
, 91 },
587 { "ENOPROTOOPT", ENOPROTOOPT
, 92 },
589 #ifdef EPROTONOSUPPORT
590 { "EPROTONOSUPPORT", EPROTONOSUPPORT
, 93 },
592 #ifdef ESOCKTNOSUPPORT
593 { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT
, 94 },
596 { "EOPNOTSUPP", EOPNOTSUPP
, 95 },
599 { "EPFNOSUPPORT", EPFNOSUPPORT
, 96 },
602 { "EAFNOSUPPORT", EAFNOSUPPORT
, 97 },
605 { "EADDRINUSE", EADDRINUSE
, 98 },
608 { "EADDRNOTAVAIL", EADDRNOTAVAIL
, 99 },
611 { "ENETDOWN", ENETDOWN
, 100 },
614 { "ENETUNREACH", ENETUNREACH
, 101 },
617 { "ENETRESET", ENETRESET
, 102 },
620 { "ECONNABORTED", ECONNABORTED
, 103 },
623 { "ECONNRESET", ECONNRESET
, 104 },
626 { "ENOBUFS", ENOBUFS
, 105 },
629 { "EISCONN", EISCONN
, 106 },
632 { "ENOTCONN", ENOTCONN
, 107 },
635 { "ESHUTDOWN", ESHUTDOWN
, 108 },
638 { "ETOOMANYREFS", ETOOMANYREFS
, 109 },
641 { "ETIMEDOUT", ETIMEDOUT
, 110 },
644 { "ECONNREFUSED", ECONNREFUSED
, 111 },
647 { "EHOSTDOWN", EHOSTDOWN
, 112 },
650 { "EHOSTUNREACH", EHOSTUNREACH
, 113 },
653 { "EALREADY", EALREADY
, 114 },
656 { "EINPROGRESS", EINPROGRESS
, 115 },
659 { "ESTALE", ESTALE
, 116 },
662 { "EUCLEAN", EUCLEAN
, 117 },
665 { "ENOTNAM", ENOTNAM
, 118 },
668 { "ENAVAIL", ENAVAIL
, 119 },
671 { "EISNAM", EISNAM
, 120 },
674 { "EREMOTEIO", EREMOTEIO
, 121 },
677 { "EDQUOT", EDQUOT
, 122 },
680 { "ENOMEDIUM", ENOMEDIUM
, 123 },
683 { "EMEDIUMTYPE", EMEDIUMTYPE
, 124 },
688 /* Extracted by applying
689 perl -ne 'if ($_ =~ /^#define/) { split;
690 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
691 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
692 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
693 installation and removing synonyms and unnecessary items. Don't
694 forget the end-marker. */
696 /* These we treat specially, as they're used in the fcntl F_GETFL
697 syscall. For consistency, open_map is also manually edited to use
699 #define TARGET_O_ACCMODE 0x3
700 #define TARGET_O_RDONLY 0x0
701 #define TARGET_O_WRONLY 0x1
703 static const CB_TARGET_DEFS_MAP open_map
[] = {
705 { "O_ACCMODE", O_ACCMODE
, TARGET_O_ACCMODE
},
708 { "O_RDONLY", O_RDONLY
, TARGET_O_RDONLY
},
711 { "O_WRONLY", O_WRONLY
, TARGET_O_WRONLY
},
714 { "O_RDWR", O_RDWR
, 0x2 },
717 { "O_CREAT", O_CREAT
, 0x40 },
720 { "O_EXCL", O_EXCL
, 0x80 },
723 { "O_NOCTTY", O_NOCTTY
, 0x100 },
726 { "O_TRUNC", O_TRUNC
, 0x200 },
729 { "O_APPEND", O_APPEND
, 0x400 },
732 { "O_NONBLOCK", O_NONBLOCK
, 0x800 },
735 { "O_NDELAY", O_NDELAY
, 0x0 },
738 { "O_SYNC", O_SYNC
, 0x1000 },
741 { "FASYNC", FASYNC
, 0x2000 },
744 { "O_DIRECT", O_DIRECT
, 0x4000 },
747 { "O_LARGEFILE", O_LARGEFILE
, 0x8000 },
750 { "O_DIRECTORY", O_DIRECTORY
, 0x10000 },
753 { "O_NOFOLLOW", O_NOFOLLOW
, 0x20000 },
758 /* Let's be less drastic and more traceable. FIXME: mark as noreturn. */
760 sim_io_error (sd, "simulator unhandled condition at %s:%d", \
761 __FUNCTION__, __LINE__)
763 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
764 static SIM_CPU
*current_cpu_for_cb_callback
;
766 static USI
create_map (SIM_DESC
, struct cris_sim_mmapped_page
**,
768 static USI
unmap_pages (SIM_DESC
, struct cris_sim_mmapped_page
**,
770 static USI
is_mapped (SIM_DESC
, struct cris_sim_mmapped_page
**,
772 static void dump_statistics (SIM_CPU
*current_cpu
);
773 static void make_first_thread (SIM_CPU
*current_cpu
);
775 /* When we risk running self-modified code (as in trampolines), this is
776 called from special-case insns. The silicon CRIS CPU:s have enough
777 cache snooping implemented making this a simulator-only issue. Tests:
778 gcc.c-torture/execute/931002-1.c execution, -O3 -g
779 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
782 cris_flush_simulator_decode_cache (SIM_CPU
*current_cpu
,
783 USI pc ATTRIBUTE_UNUSED
)
785 SIM_DESC sd
= CPU_STATE (current_cpu
);
788 if (USING_SCACHE_P (sd
))
789 scache_flush_cpu (current_cpu
);
793 /* Output statistics at the end of a run. */
795 dump_statistics (SIM_CPU
*current_cpu
)
797 SIM_DESC sd
= CPU_STATE (current_cpu
);
798 CRIS_MISC_PROFILE
*profp
799 = CPU_CRIS_MISC_PROFILE (current_cpu
);
800 unsigned64 total
= profp
->basic_cycle_count
;
801 const char *textmsg
= "Basic clock cycles, total @: %llu\n";
803 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
804 what's included in the "total" count only. */
805 switch (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
806 & FLAG_CRIS_MISC_PROFILE_ALL
)
808 case FLAG_CRIS_MISC_PROFILE_SIMPLE
:
811 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
813 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
814 total
+= profp
->unaligned_mem_dword_count
;
817 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
818 textmsg
= "Schedulable clock cycles, total @: %llu\n";
820 += (profp
->memsrc_stall_count
821 + profp
->memraw_stall_count
822 + profp
->movemsrc_stall_count
823 + profp
->movemdst_stall_count
824 + profp
->mulsrc_stall_count
825 + profp
->jumpsrc_stall_count
826 + profp
->unaligned_mem_dword_count
);
829 case FLAG_CRIS_MISC_PROFILE_ALL
:
830 textmsg
= "All accounted clock cycles, total @: %llu\n";
832 += (profp
->memsrc_stall_count
833 + profp
->memraw_stall_count
834 + profp
->movemsrc_stall_count
835 + profp
->movemdst_stall_count
836 + profp
->movemaddr_stall_count
837 + profp
->mulsrc_stall_count
838 + profp
->jumpsrc_stall_count
839 + profp
->branch_stall_count
840 + profp
->jumptarget_stall_count
841 + profp
->unaligned_mem_dword_count
);
848 "Internal inconsistency at %s:%d",
850 sim_engine_halt (sd
, current_cpu
, NULL
, 0,
851 sim_stopped
, SIM_SIGILL
);
854 /* Historically, these messages have gone to stderr, so we'll keep it
855 that way. It's also easier to then tell it from normal program
856 output. FIXME: Add redirect option like "run -e file". */
857 sim_io_eprintf (sd
, textmsg
, total
);
859 /* For v32, unaligned_mem_dword_count should always be 0. For
860 v10, memsrc_stall_count should always be 0. */
861 sim_io_eprintf (sd
, "Memory source stall cycles: %llu\n",
862 (unsigned long long) (profp
->memsrc_stall_count
863 + profp
->unaligned_mem_dword_count
));
864 sim_io_eprintf (sd
, "Memory read-after-write stall cycles: %llu\n",
865 (unsigned long long) profp
->memraw_stall_count
);
866 sim_io_eprintf (sd
, "Movem source stall cycles: %llu\n",
867 (unsigned long long) profp
->movemsrc_stall_count
);
868 sim_io_eprintf (sd
, "Movem destination stall cycles: %llu\n",
869 (unsigned long long) profp
->movemdst_stall_count
);
870 sim_io_eprintf (sd
, "Movem address stall cycles: %llu\n",
871 (unsigned long long) profp
->movemaddr_stall_count
);
872 sim_io_eprintf (sd
, "Multiplication source stall cycles: %llu\n",
873 (unsigned long long) profp
->mulsrc_stall_count
);
874 sim_io_eprintf (sd
, "Jump source stall cycles: %llu\n",
875 (unsigned long long) profp
->jumpsrc_stall_count
);
876 sim_io_eprintf (sd
, "Branch misprediction stall cycles: %llu\n",
877 (unsigned long long) profp
->branch_stall_count
);
878 sim_io_eprintf (sd
, "Jump target stall cycles: %llu\n",
879 (unsigned long long) profp
->jumptarget_stall_count
);
882 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
883 Return 1 if a overlap detected, 0 otherwise. */
886 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED
,
887 struct cris_sim_mmapped_page
**rootp
,
890 struct cris_sim_mmapped_page
*mapp
;
892 if (len
== 0 || (len
& 8191))
895 /* Iterate over the reverse-address sorted pages until we find a page in
896 or lower than the checked area. */
897 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
898 if (mapp
->addr
< addr
+ len
&& mapp
->addr
>= addr
)
904 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
905 Return 1 if the whole area is mapped, 0 otherwise. */
908 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED
,
909 struct cris_sim_mmapped_page
**rootp
,
912 struct cris_sim_mmapped_page
*mapp
;
914 if (len
== 0 || (len
& 8191))
917 /* Iterate over the reverse-address sorted pages until we find a page
918 lower than the checked area. */
919 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
920 if (addr
== mapp
->addr
&& len
== 8192)
922 else if (addr
+ len
> mapp
->addr
)
928 /* Debug helper; to be run from gdb. */
931 cris_dump_map (SIM_CPU
*current_cpu
)
933 struct cris_sim_mmapped_page
*mapp
;
936 for (mapp
= current_cpu
->highest_mmapped_page
,
937 start
= mapp
== NULL
? 0 : mapp
->addr
+ 8192,
938 end
= mapp
== NULL
? 0 : mapp
->addr
+ 8191;
942 if (mapp
->addr
!= start
- 8192)
944 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
945 end
= mapp
->addr
+ 8191;
951 if (current_cpu
->highest_mmapped_page
!= NULL
)
952 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
955 /* Create mmapped memory. ADDR is -1 if any address will do. Caller
956 must make sure that the address isn't already mapped. */
959 create_map (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
962 struct cris_sim_mmapped_page
*mapp
;
963 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
964 USI new_addr
= 0x40000000;
966 if (addr
!= (USI
) -1)
968 else if (*rootp
&& rootp
[0]->addr
>= new_addr
)
969 new_addr
= rootp
[0]->addr
+ 8192;
976 /* Which is better: return an error for this, or just round it up? */
979 /* Do a recursive call for each page in the request. */
980 for (page_addr
= new_addr
; len
!= 0; page_addr
+= 8192, len
-= 8192)
981 if (create_map (sd
, rootp
, page_addr
, 8192) >= (USI
) -8191)
988 mapp
!= NULL
&& mapp
->addr
> new_addr
;
990 higher_prevp
= &mapp
->prev
;
992 /* Assert for consistency that we don't create duplicate maps. */
993 if (is_mapped (sd
, rootp
, new_addr
, len
))
996 /* Allocate the new page, on the next higher page from the last one
997 allocated, and link in the new descriptor before previous ones. */
998 mapp
= malloc (sizeof (*mapp
));
1001 return (USI
) -ENOMEM
;
1003 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1007 mapp
->addr
= new_addr
;
1008 mapp
->prev
= *higher_prevp
;
1009 *higher_prevp
= mapp
;
1014 /* Unmap one or more pages. */
1017 unmap_pages (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
1020 struct cris_sim_mmapped_page
*mapp
;
1021 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
1029 /* Which is better: return an error for this, or just round it up? */
1032 /* Loop backwards to make each call is O(1) over the number of pages
1033 allocated, if we're unmapping from the high end of the pages. */
1034 for (page_addr
= addr
+ len
- 8192;
1037 if (unmap_pages (sd
, rootp
, page_addr
, 8192))
1040 if (unmap_pages (sd
, rootp
, addr
, 8192))
1046 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
> addr
; mapp
= mapp
->prev
)
1047 higher_prevp
= &mapp
->prev
;
1049 if (mapp
== NULL
|| mapp
->addr
!= addr
)
1052 *higher_prevp
= mapp
->prev
;
1053 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1058 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1061 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC vpc
)
1063 SIM_DESC sd
= CPU_STATE (current_cpu
);
1065 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
1069 /* Handlers from the CGEN description that should not be called. */
1072 cris_bmod_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1073 UINT srcreg ATTRIBUTE_UNUSED
,
1074 USI dstreg ATTRIBUTE_UNUSED
)
1076 SIM_DESC sd
= CPU_STATE (current_cpu
);
1081 h_supr_set_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1082 UINT index ATTRIBUTE_UNUSED
,
1083 USI page ATTRIBUTE_UNUSED
,
1084 USI newval ATTRIBUTE_UNUSED
)
1086 SIM_DESC sd
= CPU_STATE (current_cpu
);
1091 h_supr_get_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1092 UINT index ATTRIBUTE_UNUSED
,
1093 USI page ATTRIBUTE_UNUSED
)
1095 SIM_DESC sd
= CPU_STATE (current_cpu
);
1099 /* Swap one context for another. */
1102 schedule (SIM_CPU
*current_cpu
, int next
)
1104 /* Need to mark context-switches in the trace output. */
1105 if ((CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1106 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE
))
1107 cris_trace_printf (CPU_STATE (current_cpu
), current_cpu
,
1110 /* Copy the current context (if there is one) to its slot. */
1111 if (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
)
1112 memcpy (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
,
1113 ¤t_cpu
->cpu_data_placeholder
,
1114 current_cpu
->thread_cpu_data_size
);
1116 /* Copy the new context from its slot. */
1117 memcpy (¤t_cpu
->cpu_data_placeholder
,
1118 current_cpu
->thread_data
[next
].cpu_context
,
1119 current_cpu
->thread_cpu_data_size
);
1121 /* Update needed stuff to indicate the new context. */
1122 current_cpu
->threadno
= next
;
1124 /* Handle pending signals. */
1125 if (current_cpu
->thread_data
[next
].sigpending
1126 /* We don't run nested signal handlers. This means that pause(2)
1127 and sigsuspend(2) do not work in sighandlers, but that
1128 shouldn't be too hard a restriction. It also greatly
1129 simplifies the code. */
1130 && current_cpu
->thread_data
[next
].cpu_context_atsignal
== NULL
)
1134 /* See if there's really a pending, non-blocked handler. We don't
1135 queue signals, so just use the first one in ascending order. */
1136 for (sig
= 0; sig
< 64; sig
++)
1137 if (current_cpu
->thread_data
[next
].sigdata
[sig
].pending
1138 && !current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
)
1144 USI pc
= sim_pc_get (current_cpu
);
1146 /* It's simpler to save the CPU context inside the simulator
1147 than on the stack. */
1148 current_cpu
->thread_data
[next
].cpu_context_atsignal
1150 ->make_thread_cpu_data
) (current_cpu
,
1151 current_cpu
->thread_data
[next
]
1154 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1155 sp
= bfd_getl32 (regbuf
);
1157 /* Make sure we have an aligned stack. */
1160 /* Make room for the signal frame, aligned. FIXME: Check that
1161 the memory exists, map it in if absent. (BTW, should also
1162 implement on-access automatic stack allocation). */
1165 /* This isn't the same signal frame as the kernel uses, because
1166 we don't want to bother getting all registers on and off the
1169 /* First, we store the currently blocked signals. */
1171 for (i
= 0; i
< 32; i
++)
1173 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 1].blocked
<< i
;
1174 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
, blocked
);
1176 for (i
= 0; i
< 31; i
++)
1178 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 33].blocked
<< i
;
1179 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
+ 4, blocked
);
1181 /* Then, the actual instructions. This is CPU-specific, but we
1182 use instructions from the common subset for v10 and v32 which
1183 should be safe for the time being but could be parametrized
1185 /* MOVU.W [PC+],R9. */
1186 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 8, 0x9c5f);
1187 /* .WORD TARGET_SYS_sigreturn. */
1188 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 10,
1189 TARGET_SYS_sigreturn
);
1191 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 12, 0xe93d);
1193 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1194 instruction. Still, it doesn't matter because v10 has no
1195 delay slot for BREAK so it will not be executed). */
1196 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 16, 0x05b0);
1198 /* Modify registers to hold the right values for the sighandler
1199 context: updated stackpointer and return address pointing to
1200 the sigreturn stub. */
1201 bfd_putl32 (sp
, regbuf
);
1202 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1203 bfd_putl32 (sp
+ 8, regbuf
);
1204 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, TARGET_SRP_REGNUM
,
1207 current_cpu
->thread_data
[next
].sigdata
[sig
].pending
= 0;
1209 /* Block this signal (for the duration of the sighandler). */
1210 current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
= 1;
1212 sim_pc_set (current_cpu
, current_cpu
->sighandler
[sig
]);
1213 bfd_putl32 (sig
, regbuf
);
1214 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
,
1217 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1218 needed all this for, specifies a SA_SIGINFO call but treats it
1219 like an ordinary sighandler; only the signal number argument is
1220 inspected. To make future need to implement SA_SIGINFO
1221 correctly possible, we set the siginfo argument register to a
1222 magic (hopefully non-address) number. (NB: then, you should
1223 just need to pass the siginfo argument; it seems you probably
1224 don't need to implement the specific rt_sigreturn.) */
1225 bfd_putl32 (0xbad5161f, regbuf
);
1226 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R11
,
1229 /* The third argument is unused and the kernel sets it to 0. */
1230 bfd_putl32 (0, regbuf
);
1231 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R12
,
1236 /* No, there actually was no pending signal for this thread. Reset
1238 current_cpu
->thread_data
[next
].sigpending
= 0;
1242 /* Reschedule the simplest possible way until something else is absolutely
1244 - A. Find the next process (round-robin) that doesn't have at_syscall
1246 - B. If there is none, just run the next process, round-robin.
1247 - Clear at_syscall for the current process. */
1250 reschedule (SIM_CPU
*current_cpu
)
1252 SIM_DESC sd
= CPU_STATE (current_cpu
);
1255 /* Iterate over all thread slots, because after a few thread creations
1256 and exits, we don't know where the live ones are. */
1257 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1258 i
!= current_cpu
->threadno
;
1259 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1260 if (current_cpu
->thread_data
[i
].cpu_context
1261 && current_cpu
->thread_data
[i
].at_syscall
== 0)
1263 schedule (current_cpu
, i
);
1267 /* Pick any next live thread. */
1268 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1269 i
!= current_cpu
->threadno
;
1270 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1271 if (current_cpu
->thread_data
[i
].cpu_context
)
1273 schedule (current_cpu
, i
);
1277 /* More than one live thread, but we couldn't find the next one? */
1281 /* Set up everything to receive (or IGN) an incoming signal to the
1285 deliver_signal (SIM_CPU
*current_cpu
, int sig
, unsigned int pid
)
1288 USI pc
= sim_pc_get (current_cpu
);
1290 /* Find the thread index of the pid. */
1291 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
1292 /* Apparently it's ok to send signals to zombies (so a check for
1293 current_cpu->thread_data[i].cpu_context != NULL would be
1295 if (current_cpu
->thread_data
[i
].threadid
== pid
- TARGET_PID
)
1298 switch (current_cpu
->sighandler
[sig
])
1300 case TARGET_SIG_DFL
:
1303 /* The following according to the glibc
1304 documentation. (The kernel code has non-obvious
1305 execution paths.) */
1308 case TARGET_SIGSEGV
:
1310 case TARGET_SIGABRT
:
1311 case TARGET_SIGTRAP
:
1314 case TARGET_SIGTERM
:
1316 case TARGET_SIGQUIT
:
1317 case TARGET_SIGKILL
:
1320 case TARGET_SIGALRM
:
1321 case TARGET_SIGVTALRM
:
1322 case TARGET_SIGPROF
:
1323 case TARGET_SIGSTOP
:
1325 case TARGET_SIGPIPE
:
1326 case TARGET_SIGLOST
:
1327 case TARGET_SIGXCPU
:
1328 case TARGET_SIGXFSZ
:
1329 case TARGET_SIGUSR1
:
1330 case TARGET_SIGUSR2
:
1331 sim_io_eprintf (CPU_STATE (current_cpu
),
1332 "Exiting pid %d due to signal %d\n",
1334 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1335 NULL
, pc
, sim_stopped
,
1336 sig
== TARGET_SIGABRT
1337 ? SIM_SIGABRT
: SIM_SIGILL
);
1340 /* The default for all other signals is to be ignored. */
1345 case TARGET_SIG_IGN
:
1348 case TARGET_SIGKILL
:
1349 case TARGET_SIGSTOP
:
1350 /* Can't ignore these signals. */
1351 sim_io_eprintf (CPU_STATE (current_cpu
),
1352 "Exiting pid %d due to signal %d\n",
1354 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1355 NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1364 /* Mark the signal as pending, making schedule () check
1365 closer. The signal will be handled when the thread is
1366 scheduled and the signal is unblocked. */
1367 current_cpu
->thread_data
[i
].sigdata
[sig
].pending
= 1;
1368 current_cpu
->thread_data
[i
].sigpending
= 1;
1373 sim_io_eprintf (CPU_STATE (current_cpu
),
1374 "Unimplemented signal: %d\n", sig
);
1375 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
1376 sim_stopped
, SIM_SIGILL
);
1381 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu
)),
1385 /* Make the vector and the first item, the main thread. */
1388 make_first_thread (SIM_CPU
*current_cpu
)
1390 SIM_DESC sd
= CPU_STATE (current_cpu
);
1391 current_cpu
->thread_data
1393 SIM_TARGET_MAX_THREADS
1394 * sizeof (current_cpu
->thread_data
[0]));
1395 current_cpu
->thread_data
[0].cpu_context
1396 = (*current_cpu
->make_thread_cpu_data
) (current_cpu
,
1398 ->cpu_data_placeholder
);
1399 current_cpu
->thread_data
[0].parent_threadid
= -1;
1401 /* For good measure. */
1402 if (TARGET_SIG_DFL
!= 0)
1406 /* Handle unknown system calls. Returns (if it does) the syscall
1410 cris_unknown_syscall (SIM_CPU
*current_cpu
, USI pc
, char *s
, ...)
1412 SIM_DESC sd
= CPU_STATE (current_cpu
);
1413 host_callback
*cb
= STATE_CALLBACK (sd
);
1415 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
1416 || cris_unknown_syscall_action
== CRIS_USYSC_MSG_ENOSYS
)
1421 sim_io_evprintf (sd
, s
, ap
);
1424 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
)
1425 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1428 return -cb_host_to_target_errno (cb
, ENOSYS
);
1431 /* Main function: the handler of the "break 13" syscall insn. */
1434 cris_break_13_handler (SIM_CPU
*current_cpu
, USI callnum
, USI arg1
,
1435 USI arg2
, USI arg3
, USI arg4
, USI arg5
, USI arg6
,
1439 SIM_DESC sd
= CPU_STATE (current_cpu
);
1440 host_callback
*cb
= STATE_CALLBACK (sd
);
1442 int threadno
= current_cpu
->threadno
;
1444 current_cpu
->syscalls
++;
1446 CB_SYSCALL_INIT (&s
);
1452 /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need
1453 to sign-extend the lseek offset to be passed as a signed number,
1454 else we'll truncate it to something > 2GB on hosts where sizeof
1455 long > sizeof USI. We avoid doing it for all syscalls, as arg2 is
1456 e.g. an address for some syscalls. */
1457 if (callnum
== TARGET_SYS_lseek
)
1460 if (callnum
== TARGET_SYS_exit_group
1461 || (callnum
== TARGET_SYS_exit
&& current_cpu
->m1threads
== 0))
1463 if (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1464 & FLAG_CRIS_MISC_PROFILE_ALL
)
1465 dump_statistics (current_cpu
);
1466 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
1470 s
.p2
= (PTR
) current_cpu
;
1471 s
.read_mem
= sim_syscall_read_mem
;
1472 s
.write_mem
= sim_syscall_write_mem
;
1474 current_cpu_for_cb_callback
= current_cpu
;
1476 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1479 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
1481 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1484 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
1486 if (s
.errcode
!= 0 && s
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
1488 /* If the generic simulator call said ENOSYS, then let's try the
1489 ones we know ourselves.
1491 The convention is to provide *very limited* functionality on an
1492 as-needed basis, only what's covered by the test-suite, tests
1493 added when functionality changes and abort with a descriptive
1494 message for *everything* else. Where there's no test-case, we
1499 /* It's a pretty safe bet that the "old setup() system call"
1500 number will not be re-used; we can't say the same for higher
1501 numbers. We treat this simulator-generated call as "wait
1502 forever"; we re-run this insn. The wait is ended by a
1503 callback. Sanity check that this is the reason we got
1505 if (current_cpu
->thread_data
== NULL
1506 || (current_cpu
->thread_data
[threadno
].pipe_write_fd
== 0))
1507 goto unimplemented_syscall
;
1509 sim_pc_set (current_cpu
, pc
);
1513 case TARGET_SYS_fcntl64
:
1514 case TARGET_SYS_fcntl
:
1519 Glibc checks stdin, stdout and stderr fd:s for
1520 close-on-exec security sanity. We just need to provide a
1521 OK return value. If we really need to have a
1522 close-on-exec flag true, we could just do a real fcntl
1528 /* F_SETFD. Just ignore attempts to set the close-on-exec
1534 /* F_GETFL. Check for the special case for open+fdopen. */
1535 if (current_cpu
->last_syscall
== TARGET_SYS_open
1536 && arg1
== current_cpu
->last_open_fd
)
1538 retval
= current_cpu
->last_open_flags
& TARGET_O_ACCMODE
;
1543 /* Because we can't freopen fd:s 0, 1, 2 to mean
1544 something else than stdin, stdout and stderr
1545 (sim/common/syscall.c:cb_syscall special cases fd
1546 0, 1 and 2), we know what flags that we can
1547 sanely return for these fd:s. */
1548 retval
= TARGET_O_RDONLY
;
1551 else if (arg1
== 1 || arg1
== 2)
1553 retval
= TARGET_O_WRONLY
;
1558 /* Nothing else is implemented. */
1560 = cris_unknown_syscall (current_cpu
, pc
,
1561 "Unimplemented %s syscall "
1562 "(fd: 0x%lx: cmd: 0x%lx arg: "
1564 callnum
== TARGET_SYS_fcntl
1565 ? "fcntl" : "fcntl64",
1566 (unsigned long) (USI
) arg1
,
1567 (unsigned long) (USI
) arg2
,
1568 (unsigned long) (USI
) arg3
);
1573 case TARGET_SYS_uname
:
1575 /* Fill in a few constants to appease glibc. */
1576 static char sim_utsname
[6][65] =
1582 "cris", /* Overwritten below. */
1586 /* Having the hardware type in Linux equal to the bfd
1587 printable name is deliberate: if you make config.guess
1588 work on your Linux-type system the usual way, it
1589 probably will; either the bfd printable_name or the
1590 ambiguous arch_name. */
1591 strcpy (sim_utsname
[4], STATE_ARCHITECTURE (sd
)->printable_name
);
1593 if ((s
.write_mem
) (cb
, &s
, arg1
, (const char *) sim_utsname
,
1594 sizeof (sim_utsname
))
1595 != sizeof (sim_utsname
))
1596 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
1602 case TARGET_SYS_geteuid32
:
1603 /* We tell the truth with these. Maybe we shouldn't, but it
1604 should match the "stat" information. */
1605 retval
= geteuid ();
1608 case TARGET_SYS_getuid32
:
1612 case TARGET_SYS_getegid32
:
1613 retval
= getegid ();
1616 case TARGET_SYS_getgid32
:
1620 case TARGET_SYS_brk
:
1621 /* Most often, we just return the argument, like the Linux
1626 retval
= current_cpu
->endbrk
;
1627 else if (arg1
<= current_cpu
->endmem
)
1628 current_cpu
->endbrk
= arg1
;
1631 USI new_end
= (arg1
+ 8191) & ~8191;
1633 /* If the simulator wants to brk more than a certain very
1634 large amount, something is wrong. FIXME: Return an error
1635 or abort? Have command-line selectable? */
1636 if (new_end
- current_cpu
->endmem
> SIM_MAX_ALLOC_CHUNK
)
1638 current_cpu
->endbrk
= current_cpu
->endmem
;
1639 retval
= current_cpu
->endmem
;
1643 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1644 current_cpu
->endmem
,
1645 new_end
- current_cpu
->endmem
,
1647 current_cpu
->endbrk
= arg1
;
1648 current_cpu
->endmem
= new_end
;
1652 case TARGET_SYS_getpid
:
1653 /* Correct until CLONE_THREAD is implemented. */
1654 retval
= current_cpu
->thread_data
== NULL
1656 : TARGET_PID
+ current_cpu
->thread_data
[threadno
].threadid
;
1659 case TARGET_SYS_getppid
:
1660 /* Correct until CLONE_THREAD is implemented. */
1661 retval
= current_cpu
->thread_data
== NULL
1664 + current_cpu
->thread_data
[threadno
].parent_threadid
);
1667 case TARGET_SYS_mmap2
:
1676 /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1677 still masked away this bit, so let's just ignore
1679 flags
&= ~TARGET_MAP_DENYWRITE
;
1681 /* If the simulator wants to mmap more than the very large
1682 limit, something is wrong. FIXME: Return an error or
1683 abort? Have command-line selectable? */
1684 if (len
> SIM_MAX_ALLOC_CHUNK
)
1686 retval
= -cb_host_to_target_errno (cb
, ENOMEM
);
1690 if ((prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
)
1692 != (TARGET_PROT_READ
1694 | TARGET_PROT_EXEC
))
1695 && (prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
))
1696 && prot
!= TARGET_PROT_READ
)
1697 || (flags
!= (TARGET_MAP_ANONYMOUS
| TARGET_MAP_PRIVATE
)
1698 && flags
!= TARGET_MAP_PRIVATE
1699 && flags
!= (TARGET_MAP_ANONYMOUS
1700 | TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1701 && flags
!= (TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1702 && flags
!= TARGET_MAP_SHARED
)
1704 && prot
!= TARGET_PROT_READ
1705 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1706 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1707 || (fd
== (USI
) -1 && pgoff
!= 0)
1708 || (fd
!= (USI
) -1 && (flags
& TARGET_MAP_ANONYMOUS
)))
1711 = cris_unknown_syscall (current_cpu
, pc
,
1712 "Unimplemented mmap2 call "
1713 "(0x%lx, 0x%lx, 0x%lx, "
1714 "0x%lx, 0x%lx, 0x%lx)\n",
1715 (unsigned long) arg1
,
1716 (unsigned long) arg2
,
1717 (unsigned long) arg3
,
1718 (unsigned long) arg4
,
1719 (unsigned long) arg5
,
1720 (unsigned long) arg6
);
1723 else if (fd
!= (USI
) -1)
1730 /* A non-aligned argument is allowed for files. */
1731 USI newlen
= (len
+ 8191) & ~8191;
1733 /* We only support read, read|exec, and read|write,
1734 which we should already have checked. Check again
1736 if (prot
!= TARGET_PROT_READ
1737 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1738 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1741 if (flags
& TARGET_MAP_FIXED
)
1742 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1744 else if (is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1749 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1750 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1754 if (newaddr
>= (USI
) -8191)
1757 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1761 /* We were asked for MAP_FIXED, but couldn't. */
1762 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1765 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1767 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1771 /* Find the current position in the file. */
1772 s
.func
= TARGET_SYS_lseek
;
1776 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1783 /* Move to the correct offset in the file. */
1784 s
.func
= TARGET_SYS_lseek
;
1786 s
.arg2
= pgoff
*8192;
1788 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1794 /* Use the standard read callback to read in "len"
1796 s
.func
= TARGET_SYS_read
;
1800 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1803 /* If the result is a page or more lesser than what
1804 was requested, something went wrong. */
1805 if (len
>= 8192 && (USI
) s
.result
<= len
- 8192)
1808 /* After reading, we need to go back to the previous
1809 position in the file. */
1810 s
.func
= TARGET_SYS_lseek
;
1814 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1816 if (pos
!= (USI
) s
.result
)
1823 USI newlen
= (len
+ 8191) & ~8191;
1826 if (flags
& TARGET_MAP_FIXED
)
1827 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1829 else if (is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1833 newaddr
= create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1834 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1838 if (newaddr
>= (USI
) -8191)
1839 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1843 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1846 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1848 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1855 case TARGET_SYS_mprotect
:
1857 /* We only cover the case of linuxthreads mprotecting out
1858 its stack guard page and of dynamic loading mprotecting
1859 away the data (for some reason the whole library, then
1860 mprotects away the data part and mmap-FIX:es it again. */
1865 if (prot
!= TARGET_PROT_NONE
1866 || !is_mapped_only (sd
, ¤t_cpu
->highest_mmapped_page
,
1867 addr
, (len
+ 8191) & ~8191))
1870 = cris_unknown_syscall (current_cpu
, pc
,
1871 "Unimplemented mprotect call "
1872 "(0x%lx, 0x%lx, 0x%lx)\n",
1873 (unsigned long) arg1
,
1874 (unsigned long) arg2
,
1875 (unsigned long) arg3
);
1879 /* Just ignore this. We could make this equal to munmap,
1880 but then we'd have to make sure no anon mmaps gets this
1881 address before a subsequent MAP_FIXED mmap intended to
1887 case TARGET_SYS_ioctl
:
1889 /* We support only a very limited functionality: checking
1890 stdout with TCGETS to perform the isatty function. The
1891 TCGETS ioctl isn't actually performed or the result used by
1892 an isatty () caller in a "hello, world" program; only the
1893 return value is then used. Maybe we shouldn't care about
1894 the environment of the simulator regarding isatty, but
1895 that's been working before, in the xsim simulator. */
1896 if (arg2
== TARGET_TCGETS
&& arg1
== 1)
1897 retval
= isatty (1) ? 0 : cb_host_to_target_errno (cb
, EINVAL
);
1899 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1903 case TARGET_SYS_munmap
:
1908 = unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1910 retval
= result
!= 0 ? -cb_host_to_target_errno (cb
, result
) : 0;
1914 case TARGET_SYS_wait4
:
1922 /* FIXME: We're not properly implementing __WCLONE, and we
1923 don't really need the special casing so we might as well
1924 make this general. */
1925 if ((!(pid
== (USI
) -1
1926 && options
== (TARGET___WCLONE
| TARGET_WNOHANG
)
1929 && (options
== TARGET___WCLONE
1930 || options
== TARGET___WALL
)))
1932 || current_cpu
->thread_data
== NULL
)
1935 = cris_unknown_syscall (current_cpu
, pc
,
1936 "Unimplemented wait4 call "
1937 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1938 (unsigned long) arg1
,
1939 (unsigned long) arg2
,
1940 (unsigned long) arg3
,
1941 (unsigned long) arg4
);
1945 if (pid
== (USI
) -1)
1946 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1948 if (current_cpu
->thread_data
[threadno
].threadid
1949 == current_cpu
->thread_data
[i
].parent_threadid
1950 && current_cpu
->thread_data
[i
].threadid
!= 0
1951 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1953 /* A zombied child. Get the exit value and clear the
1954 zombied entry so it will be reused. */
1955 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, saddr
,
1957 ->thread_data
[i
].exitval
);
1959 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1960 memset (¤t_cpu
->thread_data
[i
], 0,
1961 sizeof (current_cpu
->thread_data
[i
]));
1967 /* We're waiting for a specific PID. If we don't find
1968 it zombied on this run, rerun the syscall. */
1969 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1970 if (pid
== current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
1971 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1974 /* Get the exit value if the caller wants it. */
1975 sim_core_write_unaligned_4 (current_cpu
, pc
, 0,
1982 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1983 memset (¤t_cpu
->thread_data
[i
], 0,
1984 sizeof (current_cpu
->thread_data
[i
]));
1989 sim_pc_set (current_cpu
, pc
);
1992 retval
= -cb_host_to_target_errno (cb
, ECHILD
);
1997 case TARGET_SYS_rt_sigaction
:
2005 __sighandler_t sa_handler;
2006 unsigned long sa_flags;
2007 void (*sa_restorer)(void);
2013 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, old_sa
+ 0,
2014 current_cpu
->sighandler
[signum
]);
2015 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 4, 0);
2016 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 8, 0);
2018 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
2019 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 12, 0);
2020 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 16, 0);
2024 USI target_sa_handler
2025 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
);
2027 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 4);
2028 USI target_sa_restorer
2029 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 8);
2030 USI target_sa_mask_low
2031 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 12);
2032 USI target_sa_mask_high
2033 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 16);
2035 /* We won't interrupt a syscall so we won't restart it,
2036 but a signal(2) call ends up syscalling rt_sigaction
2037 with this flag, so we have to handle it. The
2038 sa_restorer field contains garbage when not
2039 TARGET_SA_RESTORER, so don't look at it. For the
2040 time being, we don't nest sighandlers, so we
2041 ignore the sa_mask, which simplifies things. */
2042 if ((target_sa_flags
!= 0
2043 && target_sa_flags
!= TARGET_SA_RESTART
2044 && target_sa_flags
!= (TARGET_SA_RESTART
|TARGET_SA_SIGINFO
))
2045 || target_sa_handler
== 0)
2048 = cris_unknown_syscall (current_cpu
, pc
,
2049 "Unimplemented rt_sigaction "
2052 "[0x%x, 0x%x, 0x%x, "
2053 "{0x%x, 0x%x}], 0x%lx)\n",
2054 (unsigned long) arg1
,
2055 (unsigned long) arg2
,
2060 target_sa_mask_high
,
2061 (unsigned long) arg3
);
2065 current_cpu
->sighandler
[signum
] = target_sa_handler
;
2067 /* Because we may have unblocked signals, one may now be
2068 pending, if there are threads, that is. */
2069 if (current_cpu
->thread_data
)
2070 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2076 case TARGET_SYS_mremap
:
2082 USI new_addr
= arg5
;
2085 if (new_len
== old_len
)
2086 /* The program and/or library is possibly confused but
2087 this is a valid call. Happens with ipps-1.40 on file
2090 else if (new_len
< old_len
)
2092 /* Shrinking is easy. */
2093 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2094 addr
+ new_len
, old_len
- new_len
) != 0)
2095 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2099 else if (! is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
2100 addr
+ old_len
, new_len
- old_len
))
2102 /* If the extension isn't mapped, we can just add it. */
2104 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2105 addr
+ old_len
, new_len
- old_len
);
2107 if (mapped_addr
> (USI
) -8192)
2108 retval
= -cb_host_to_target_errno (cb
, -(SI
) mapped_addr
);
2112 else if (flags
& TARGET_MREMAP_MAYMOVE
)
2114 /* Create a whole new map and copy the contents
2115 block-by-block there. We ignore the new_addr argument
2118 USI prev_addr
= addr
;
2119 USI prev_len
= old_len
;
2122 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2125 if (mapped_addr
> (USI
) -8192)
2127 retval
= -cb_host_to_target_errno (cb
, -(SI
) new_addr
);
2131 retval
= mapped_addr
;
2134 old_len
-= 8192, mapped_addr
+= 8192, addr
+= 8192)
2136 if (sim_core_read_buffer (sd
, current_cpu
, read_map
, buf
,
2138 || sim_core_write_buffer (sd
, current_cpu
, 0, buf
,
2139 mapped_addr
, 8192) != 8192)
2143 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2144 prev_addr
, prev_len
) != 0)
2148 retval
= -cb_host_to_target_errno (cb
, -ENOMEM
);
2152 case TARGET_SYS_poll
:
2154 int npollfds
= arg2
;
2170 /* Check that this is the expected poll call from
2171 linuxthreads/manager.c; we don't support anything else.
2172 Remember, fd == 0 isn't supported. */
2174 || ((fd
= sim_core_read_unaligned_4 (current_cpu
, pc
,
2176 || ((events
= sim_core_read_unaligned_2 (current_cpu
, pc
,
2179 || ((cb
->to_fstat
) (cb
, fd
, &buf
) != 0
2180 || (buf
.st_mode
& S_IFIFO
) == 0)
2181 || current_cpu
->thread_data
== NULL
)
2184 = cris_unknown_syscall (current_cpu
, pc
,
2185 "Unimplemented poll syscall "
2186 "(0x%lx: [0x%x, 0x%x, x], "
2188 (unsigned long) arg1
, fd
, events
,
2189 (unsigned long) arg2
,
2190 (unsigned long) arg3
);
2196 /* Iterate over threads; find a marker that a writer is
2197 sleeping, waiting for a reader. */
2198 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2199 if (current_cpu
->thread_data
[i
].cpu_context
!= NULL
2200 && current_cpu
->thread_data
[i
].pipe_read_fd
== fd
)
2202 revents
= TARGET_POLLIN
;
2207 /* Timeout decreases with whatever time passed between the
2208 last syscall and this. That's not exactly right for the
2209 first call, but it's close enough that it isn't
2210 worthwhile to complicate matters by making that a special
2213 -= (TARGET_TIME_MS (current_cpu
)
2214 - (current_cpu
->thread_data
[threadno
].last_execution
));
2216 /* Arrange to repeat this syscall until timeout or event,
2217 decreasing timeout at each iteration. */
2218 if (timeout
> 0 && revents
== 0)
2220 bfd_byte timeout_buf
[4];
2222 bfd_putl32 (timeout
, timeout_buf
);
2223 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2224 H_GR_R12
, timeout_buf
, 4);
2225 sim_pc_set (current_cpu
, pc
);
2230 sim_core_write_unaligned_2 (current_cpu
, pc
, 0, ufds
+ 4 + 2,
2235 case TARGET_SYS_time
:
2237 retval
= (int) (*cb
->time
) (cb
, 0L);
2239 /* At time of this writing, CB_SYSCALL_time doesn't do the
2240 part of setting *arg1 to the return value. */
2242 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, retval
);
2246 case TARGET_SYS_gettimeofday
:
2249 USI ts
= TARGET_TIME (current_cpu
);
2250 USI tms
= TARGET_TIME_MS (current_cpu
);
2252 /* First dword is seconds since TARGET_EPOCH. */
2253 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, ts
);
2255 /* Second dword is microseconds. */
2256 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4,
2257 (tms
% 1000) * 1000);
2261 /* Time-zone info is always cleared. */
2262 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, 0);
2263 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, 0);
2268 case TARGET_SYS_llseek
:
2270 /* If it fits, tweak parameters to fit the "generic" 32-bit
2271 lseek and use that. */
2279 if (!((offs_hi
== 0 && offs_lo
>= 0)
2280 || (offs_hi
== -1 && offs_lo
< 0)))
2283 = cris_unknown_syscall (current_cpu
, pc
,
2284 "Unimplemented llseek offset,"
2285 " fd %d: 0x%x:0x%x\n",
2286 fd
, (unsigned) arg2
,
2291 s
.func
= TARGET_SYS_lseek
;
2294 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2296 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
2298 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2301 retval
= -s
.errcode
;
2304 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
,
2306 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
+ 4,
2307 s
.result
< 0 ? -1 : 0);
2312 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2315 void *iov_base; Starting address
2316 size_t iov_len; Number of bytes to transfer
2318 case TARGET_SYS_writev
:
2326 /* We'll ignore strict error-handling and just do multiple write calls. */
2327 for (i
= 0; i
< iovcnt
; i
++)
2331 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2334 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2337 s
.func
= TARGET_SYS_write
;
2342 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2344 sysret
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2346 if (sysret
!= iov_len
)
2361 /* This one does have a generic callback function, but at the time
2362 of this writing, cb_syscall does not have code for it, and we
2363 need target-specific code for the threads implementation
2365 case TARGET_SYS_kill
:
2372 /* At kill(2), glibc sets signal masks such that the thread
2373 machinery is initialized. Still, there is and was only
2375 if (current_cpu
->max_threadid
== 0)
2377 if (pid
!= TARGET_PID
)
2379 retval
= -cb_host_to_target_errno (cb
, EPERM
);
2383 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2384 if (sig
== TARGET_SIGABRT
)
2385 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2386 the end-point for failing GCC test-cases. */
2387 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2391 sim_io_eprintf (sd
, "Unimplemented signal: %d\n", sig
);
2392 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2396 /* This will not be reached. */
2400 retval
= deliver_signal (current_cpu
, sig
, pid
);
2404 case TARGET_SYS_rt_sigprocmask
:
2411 if (how
!= TARGET_SIG_BLOCK
2412 && how
!= TARGET_SIG_SETMASK
2413 && how
!= TARGET_SIG_UNBLOCK
)
2416 = cris_unknown_syscall (current_cpu
, pc
,
2417 "Unimplemented rt_sigprocmask "
2418 "syscall (0x%x, 0x%x, 0x%x)\n",
2426 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2429 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2432 /* The sigmask is kept in the per-thread data, so we may
2433 need to create the first one. */
2434 if (current_cpu
->thread_data
== NULL
)
2435 make_first_thread (current_cpu
);
2437 if (how
== TARGET_SIG_SETMASK
)
2438 for (i
= 0; i
< 64; i
++)
2439 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
= 0;
2441 for (i
= 0; i
< 32; i
++)
2442 if ((set_low
& (1 << i
)))
2443 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2444 = (how
!= TARGET_SIG_UNBLOCK
);
2446 for (i
= 0; i
< 31; i
++)
2447 if ((set_high
& (1 << i
)))
2448 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2449 = (how
!= TARGET_SIG_UNBLOCK
);
2451 /* The mask changed, so a signal may be unblocked for
2453 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2461 for (i
= 0; i
< 32; i
++)
2462 if (current_cpu
->thread_data
[threadno
]
2463 .sigdata
[i
+ 1].blocked
)
2465 for (i
= 0; i
< 31; i
++)
2466 if (current_cpu
->thread_data
[threadno
]
2467 .sigdata
[i
+ 33].blocked
)
2470 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 0, set_low
);
2471 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 4, set_high
);
2478 case TARGET_SYS_sigreturn
:
2482 int was_sigsuspended
;
2484 if (current_cpu
->thread_data
== NULL
2485 /* The CPU context is saved with the simulator data, not
2486 on the stack as in the real world. */
2487 || (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
2491 = cris_unknown_syscall (current_cpu
, pc
,
2492 "Invalid sigreturn syscall: "
2493 "no signal handler active "
2494 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2496 (unsigned long) arg1
,
2497 (unsigned long) arg2
,
2498 (unsigned long) arg3
,
2499 (unsigned long) arg4
,
2500 (unsigned long) arg5
,
2501 (unsigned long) arg6
);
2506 = current_cpu
->thread_data
[threadno
].sigsuspended
;
2508 /* Restore the sigmask, either from the stack copy made when
2509 the sighandler was called, or from the saved state
2510 specifically for sigsuspend(2). */
2511 if (was_sigsuspended
)
2513 current_cpu
->thread_data
[threadno
].sigsuspended
= 0;
2514 for (i
= 0; i
< 64; i
++)
2515 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
2516 = current_cpu
->thread_data
[threadno
]
2517 .sigdata
[i
].blocked_suspendsave
;
2525 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2526 H_GR_SP
, regbuf
, 4);
2527 sp
= bfd_getl32 (regbuf
);
2529 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
);
2531 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
+ 4);
2533 for (i
= 0; i
< 32; i
++)
2534 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2535 = (set_low
& (1 << i
)) != 0;
2536 for (i
= 0; i
< 31; i
++)
2537 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2538 = (set_high
& (1 << i
)) != 0;
2541 /* The mask changed, so a signal may be unblocked for
2543 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2545 memcpy (¤t_cpu
->cpu_data_placeholder
,
2546 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
,
2547 current_cpu
->thread_cpu_data_size
);
2548 free (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
);
2549 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
= NULL
;
2551 /* The return value must come from the saved R10. */
2552 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, regbuf
, 4);
2553 retval
= bfd_getl32 (regbuf
);
2555 /* We must also break the "sigsuspension loop". */
2556 if (was_sigsuspended
)
2557 sim_pc_set (current_cpu
, sim_pc_get (current_cpu
) + 2);
2561 case TARGET_SYS_rt_sigsuspend
:
2569 = cris_unknown_syscall (current_cpu
, pc
,
2570 "Unimplemented rt_sigsuspend syscall"
2571 " arguments (0x%lx, 0x%lx)\n",
2572 (unsigned long) arg1
,
2573 (unsigned long) arg2
);
2577 /* Don't change the signal mask if we're already in
2578 sigsuspend state (i.e. this syscall is a rerun). */
2579 else if (!current_cpu
->thread_data
[threadno
].sigsuspended
)
2582 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2585 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2589 /* Save the current sigmask and insert the user-supplied
2591 for (i
= 0; i
< 32; i
++)
2593 current_cpu
->thread_data
[threadno
]
2594 .sigdata
[i
+ 1].blocked_suspendsave
2595 = current_cpu
->thread_data
[threadno
]
2596 .sigdata
[i
+ 1].blocked
;
2598 current_cpu
->thread_data
[threadno
]
2599 .sigdata
[i
+ 1].blocked
= (set_low
& (1 << i
)) != 0;
2601 for (i
= 0; i
< 31; i
++)
2603 current_cpu
->thread_data
[threadno
]
2604 .sigdata
[i
+ 33].blocked_suspendsave
2605 = current_cpu
->thread_data
[threadno
]
2606 .sigdata
[i
+ 33].blocked
;
2607 current_cpu
->thread_data
[threadno
]
2608 .sigdata
[i
+ 33].blocked
= (set_high
& (1 << i
)) != 0;
2611 current_cpu
->thread_data
[threadno
].sigsuspended
= 1;
2613 /* The mask changed, so a signal may be unblocked for
2615 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2618 /* Because we don't use arg1 (newsetp) when this syscall is
2619 rerun, it doesn't matter that we overwrite it with the
2620 (constant) return value. */
2621 retval
= -cb_host_to_target_errno (cb
, EINTR
);
2622 sim_pc_set (current_cpu
, pc
);
2626 /* Add case labels here for other syscalls using the 32-bit
2627 "struct stat", provided they have a corresponding simulator
2628 function of course. */
2629 case TARGET_SYS_stat
:
2630 case TARGET_SYS_fstat
:
2632 /* As long as the infrastructure doesn't cache anything
2633 related to the stat mapping, this trick gets us a dual
2634 "struct stat"-type mapping in the least error-prone way. */
2635 const char *saved_map
= cb
->stat_map
;
2636 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
2638 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_stat32_map
;
2639 cb
->stat_map
= stat32_map
;
2641 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2644 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2647 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2649 cb
->stat_map
= saved_map
;
2650 cb
->syscall_map
= saved_syscall_map
;
2654 case TARGET_SYS_getcwd
:
2659 char *cwd
= xmalloc (SIM_PATHMAX
);
2660 if (cwd
!= getcwd (cwd
, SIM_PATHMAX
))
2663 /* FIXME: When and if we support chdir, we need something
2664 a bit more elaborate. */
2665 if (simulator_sysroot
[0] != '\0')
2668 retval
= -cb_host_to_target_errno (cb
, ERANGE
);
2669 if (strlen (cwd
) + 1 <= size
)
2671 retval
= strlen (cwd
) + 1;
2672 if (sim_core_write_buffer (sd
, current_cpu
, 0, cwd
,
2674 != (unsigned int) retval
)
2675 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2681 case TARGET_SYS_access
:
2685 char *pbuf
= xmalloc (SIM_PATHMAX
);
2690 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2692 strcpy (pbuf
, simulator_sysroot
);
2693 o
+= strlen (simulator_sysroot
);
2696 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2699 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2700 if (pbuf
[i
+ o
] == 0)
2704 if (i
+ o
== SIM_PATHMAX
)
2706 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2710 /* Assert that we don't get calls for files for which we
2711 don't have support. */
2712 if (strncmp (pbuf
+ strlen (simulator_sysroot
),
2715 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2722 if (access (pbuf
, hmode
) != 0)
2723 retval
= -cb_host_to_target_errno (cb
, errno
);
2731 case TARGET_SYS_readlink
:
2736 char *pbuf
= xmalloc (SIM_PATHMAX
);
2737 char *lbuf
= xmalloc (SIM_PATHMAX
);
2738 char *lbuf_alloc
= lbuf
;
2743 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2745 strcpy (pbuf
, simulator_sysroot
);
2746 o
+= strlen (simulator_sysroot
);
2749 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2752 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2753 if (pbuf
[i
+ o
] == 0)
2757 if (i
+ o
== SIM_PATHMAX
)
2759 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2763 /* Intervene calls for certain files expected in the target
2764 proc file system. */
2765 if (strcmp (pbuf
+ strlen (simulator_sysroot
),
2766 "/proc/" XSTRING (TARGET_PID
) "/exe") == 0)
2769 = (STATE_PROG_ARGV (sd
) != NULL
2770 ? *STATE_PROG_ARGV (sd
) : NULL
);
2772 if (argv0
== NULL
|| *argv0
== '.')
2775 = cris_unknown_syscall (current_cpu
, pc
,
2776 "Unimplemented readlink syscall "
2777 "(0x%lx: [\"%s\"], 0x%lx)\n",
2778 (unsigned long) arg1
, pbuf
,
2779 (unsigned long) arg2
);
2782 else if (*argv0
== '/')
2784 if (strncmp (simulator_sysroot
, argv0
,
2785 strlen (simulator_sysroot
)) == 0)
2786 argv0
+= strlen (simulator_sysroot
);
2788 strcpy (lbuf
, argv0
);
2789 nchars
= strlen (argv0
) + 1;
2793 if (getcwd (lbuf
, SIM_PATHMAX
) != NULL
2794 && strlen (lbuf
) + 2 + strlen (argv0
) < SIM_PATHMAX
)
2796 if (strncmp (simulator_sysroot
, lbuf
,
2797 strlen (simulator_sysroot
)) == 0)
2798 lbuf
+= strlen (simulator_sysroot
);
2801 strcat (lbuf
, argv0
);
2802 nchars
= strlen (lbuf
) + 1;
2809 nchars
= readlink (pbuf
, lbuf
, SIM_PATHMAX
);
2811 /* We trust that the readlink result returns a *relative*
2812 link, or one already adjusted for the file-path-prefix.
2813 (We can't generally tell the difference, so we go with
2814 the easiest decision; no adjustment.) */
2818 retval
= -cb_host_to_target_errno (cb
, errno
);
2822 if (bufsiz
< nchars
)
2825 if (sim_core_write_buffer (sd
, current_cpu
, write_map
, lbuf
,
2826 buf
, nchars
) != (unsigned int) nchars
)
2827 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2836 case TARGET_SYS_sched_getscheduler
:
2840 /* FIXME: Search (other) existing threads. */
2841 if (pid
!= 0 && pid
!= TARGET_PID
)
2842 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2844 retval
= TARGET_SCHED_OTHER
;
2848 case TARGET_SYS_sched_getparam
:
2854 struct sched_param {
2858 if (pid
!= 0 && pid
!= TARGET_PID
)
2859 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2862 /* FIXME: Save scheduler setting before threads are
2864 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, paramp
,
2865 current_cpu
->thread_data
!= NULL
2867 ->thread_data
[threadno
]
2875 case TARGET_SYS_sched_setparam
:
2880 if ((pid
!= 0 && pid
!= TARGET_PID
)
2881 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2883 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2889 case TARGET_SYS_sched_setscheduler
:
2895 if ((pid
!= 0 && pid
!= TARGET_PID
)
2896 || policy
!= TARGET_SCHED_OTHER
2897 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2899 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2901 /* FIXME: Save scheduler setting to be read in later
2902 sched_getparam calls. */
2907 case TARGET_SYS_sched_yield
:
2908 /* We reschedule to the next thread after a syscall anyway, so
2909 we don't have to do anything here than to set the return
2914 case TARGET_SYS_sched_get_priority_min
:
2915 case TARGET_SYS_sched_get_priority_max
:
2917 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2922 case TARGET_SYS_ugetrlimit
:
2924 unsigned int curlim
, maxlim
;
2925 if (arg1
!= TARGET_RLIMIT_STACK
&& arg1
!= TARGET_RLIMIT_NOFILE
)
2927 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2933 unsigned long rlim_cur;
2934 unsigned long rlim_max;
2936 if (arg1
== TARGET_RLIMIT_NOFILE
)
2938 /* Sadly a very low limit. Better not lie, though. */
2939 maxlim
= curlim
= MAX_CALLBACK_FDS
;
2941 else /* arg1 == TARGET_RLIMIT_STACK */
2943 maxlim
= 0xffffffff;
2946 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, curlim
);
2947 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, maxlim
);
2952 case TARGET_SYS_setrlimit
:
2953 if (arg1
!= TARGET_RLIMIT_STACK
)
2955 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2958 /* FIXME: Save values for future ugetrlimit calls. */
2962 /* Provide a very limited subset of the sysctl functions, and
2963 abort for the rest. */
2964 case TARGET_SYS__sysctl
:
2967 struct __sysctl_args {
2974 unsigned long __unused[4];
2976 SI name
= sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
);
2977 SI name0
= name
== 0
2978 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
);
2979 SI name1
= name
== 0
2980 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
+ 4);
2982 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4);
2984 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 8);
2986 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 12);
2987 SI oldlen
= oldlenp
== 0
2988 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, oldlenp
);
2990 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 16);
2992 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 20);
2994 if (name0
== TARGET_CTL_KERN
&& name1
== TARGET_CTL_KERN_VERSION
)
2996 SI to_write
= oldlen
< (SI
) sizeof (TARGET_UTSNAME
)
2997 ? oldlen
: (SI
) sizeof (TARGET_UTSNAME
);
2999 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldlenp
,
3000 sizeof (TARGET_UTSNAME
));
3002 if (sim_core_write_buffer (sd
, current_cpu
, write_map
,
3003 TARGET_UTSNAME
, oldval
,
3005 != (unsigned int) to_write
)
3006 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
3013 = cris_unknown_syscall (current_cpu
, pc
,
3014 "Unimplemented _sysctl syscall "
3015 "(0x%lx: [0x%lx, 0x%lx],"
3016 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
3017 (unsigned long) name
,
3018 (unsigned long) name0
,
3019 (unsigned long) name1
,
3020 (unsigned long) nlen
,
3021 (unsigned long) oldval
,
3022 (unsigned long) oldlenp
,
3023 (unsigned long) newval
,
3024 (unsigned long) newlen
);
3028 case TARGET_SYS_exit
:
3030 /* Here for all but the last thread. */
3033 = current_cpu
->thread_data
[threadno
].threadid
+ TARGET_PID
;
3035 = (current_cpu
->thread_data
[threadno
].parent_threadid
3037 int exitsig
= current_cpu
->thread_data
[threadno
].exitsig
;
3039 /* Any children are now all orphans. */
3040 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3041 if (current_cpu
->thread_data
[i
].parent_threadid
3042 == current_cpu
->thread_data
[threadno
].threadid
)
3043 /* Make getppid(2) return 1 for them, poor little ones. */
3044 current_cpu
->thread_data
[i
].parent_threadid
= -TARGET_PID
+ 1;
3046 /* Free the cpu context data. When the parent has received
3047 the exit status, we'll clear the entry too. */
3048 free (current_cpu
->thread_data
[threadno
].cpu_context
);
3049 current_cpu
->thread_data
[threadno
].cpu_context
= NULL
;
3050 current_cpu
->m1threads
--;
3053 sim_io_eprintf (sd
, "Thread %d exited with status %d\n",
3055 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
3059 /* Still, we may want to support non-zero exit values. */
3060 current_cpu
->thread_data
[threadno
].exitval
= arg1
<< 8;
3063 deliver_signal (current_cpu
, exitsig
, ppid
);
3067 case TARGET_SYS_clone
:
3069 int nthreads
= current_cpu
->m1threads
+ 1;
3070 void *thread_cpu_data
;
3071 bfd_byte old_sp_buf
[4];
3073 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3076 /* That's right, the syscall clone arguments are reversed
3077 compared to sys_clone notes in clone(2) and compared to
3078 other Linux ports (i.e. it's the same order as in the
3079 clone(2) libcall). */
3083 if (nthreads
== SIM_TARGET_MAX_THREADS
)
3085 retval
= -cb_host_to_target_errno (cb
, EAGAIN
);
3089 /* FIXME: Implement the low byte. */
3090 if ((flags
& ~TARGET_CSIGNAL
) !=
3093 | TARGET_CLONE_FILES
3094 | TARGET_CLONE_SIGHAND
)
3098 = cris_unknown_syscall (current_cpu
, pc
,
3099 "Unimplemented clone syscall "
3101 (unsigned long) arg1
,
3102 (unsigned long) arg2
);
3106 if (current_cpu
->thread_data
== NULL
)
3107 make_first_thread (current_cpu
);
3109 /* The created thread will get the new SP and a cleared R10.
3110 Since it's created out of a copy of the old thread and we
3111 don't have a set-register-function that just take the
3112 cpu_data as a parameter, we set the childs values first,
3113 and write back or overwrite them in the parent after the
3115 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
3116 H_GR_SP
, old_sp_buf
, 4);
3117 bfd_putl32 (newsp
, sp_buf
);
3118 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3119 H_GR_SP
, sp_buf
, 4);
3120 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3121 H_GR_R10
, (bfd_byte
*) zeros
, 4);
3124 ->make_thread_cpu_data
) (current_cpu
,
3125 ¤t_cpu
->cpu_data_placeholder
);
3126 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3127 H_GR_SP
, old_sp_buf
, 4);
3129 retval
= ++current_cpu
->max_threadid
+ TARGET_PID
;
3131 /* Find an unused slot. After a few threads have been created
3132 and exited, the array is expected to be a bit fragmented.
3133 We don't reuse the first entry, though, that of the
3135 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
3136 if (current_cpu
->thread_data
[i
].cpu_context
== NULL
3137 /* Don't reuse a zombied entry. */
3138 && current_cpu
->thread_data
[i
].threadid
== 0)
3141 memcpy (¤t_cpu
->thread_data
[i
],
3142 ¤t_cpu
->thread_data
[threadno
],
3143 sizeof (current_cpu
->thread_data
[i
]));
3144 current_cpu
->thread_data
[i
].cpu_context
= thread_cpu_data
;
3145 current_cpu
->thread_data
[i
].cpu_context_atsignal
= NULL
;
3146 current_cpu
->thread_data
[i
].threadid
= current_cpu
->max_threadid
;
3147 current_cpu
->thread_data
[i
].parent_threadid
3148 = current_cpu
->thread_data
[threadno
].threadid
;
3149 current_cpu
->thread_data
[i
].pipe_read_fd
= 0;
3150 current_cpu
->thread_data
[i
].pipe_write_fd
= 0;
3151 current_cpu
->thread_data
[i
].at_syscall
= 0;
3152 current_cpu
->thread_data
[i
].sigpending
= 0;
3153 current_cpu
->thread_data
[i
].sigsuspended
= 0;
3154 current_cpu
->thread_data
[i
].exitsig
= flags
& TARGET_CSIGNAL
;
3155 current_cpu
->m1threads
= nthreads
;
3159 /* Better watch these in case they do something necessary. */
3160 case TARGET_SYS_socketcall
:
3161 retval
= -cb_host_to_target_errno (cb
, ENOSYS
);
3164 case TARGET_SYS_set_thread_area
:
3165 /* Do the same error check as Linux. */
3168 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
3171 (*current_cpu
->set_target_thread_data
) (current_cpu
, arg1
);
3175 unimplemented_syscall
:
3178 = cris_unknown_syscall (current_cpu
, pc
,
3179 "Unimplemented syscall: %d "
3180 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3181 callnum
, arg1
, arg2
, arg3
, arg4
, arg5
,
3186 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
3187 if (callnum
== TARGET_SYS_open
)
3189 current_cpu
->last_open_fd
= retval
;
3190 current_cpu
->last_open_flags
= arg2
;
3193 current_cpu
->last_syscall
= callnum
;
3195 /* A system call is a rescheduling point. For the time being, we don't
3196 reschedule anywhere else. */
3197 if (current_cpu
->m1threads
!= 0
3198 /* We need to schedule off from an exiting thread that is the
3200 || (current_cpu
->thread_data
!= NULL
3201 && current_cpu
->thread_data
[threadno
].cpu_context
== NULL
))
3203 bfd_byte retval_buf
[4];
3205 current_cpu
->thread_data
[threadno
].last_execution
3206 = TARGET_TIME_MS (current_cpu
);
3207 bfd_putl32 (retval
, retval_buf
);
3208 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3210 current_cpu
->thread_data
[threadno
].at_syscall
= 1;
3211 reschedule (current_cpu
);
3213 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3214 retval
= bfd_getl32 (retval_buf
);
3220 /* Callback from simulator write saying that the pipe at (reader, writer)
3221 is now non-empty (so the writer should wait until the pipe is empty, at
3222 least not write to this or any other pipe). Simplest is to just wait
3223 until the pipe is empty. */
3226 cris_pipe_nonempty (host_callback
*cb ATTRIBUTE_UNUSED
,
3227 int reader
, int writer
)
3229 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3230 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3232 /* It's the current thread: we just have to re-run the current
3233 syscall instruction (presumably "break 13") and change the syscall
3234 to the special simulator-wait code. Oh, and set a marker that
3235 we're waiting, so we can disambiguate the special call from a
3238 This function may be called multiple times between cris_pipe_empty,
3239 but we must avoid e.g. decreasing PC every time. Check fd markers
3241 if (cpu
->thread_data
== NULL
)
3243 sim_io_eprintf (CPU_STATE (cpu
),
3244 "Terminating simulation due to writing pipe rd:wr %d:%d"
3245 " from one single thread\n", reader
, writer
);
3246 sim_engine_halt (CPU_STATE (cpu
), cpu
,
3247 NULL
, sim_pc_get (cpu
), sim_stopped
, SIM_SIGILL
);
3249 else if (cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
== 0)
3251 cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
= writer
;
3252 cpu
->thread_data
[cpu
->threadno
].pipe_read_fd
= reader
;
3253 /* FIXME: We really shouldn't change registers other than R10 in
3254 syscalls (like R9), here or elsewhere. */
3255 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R9
, (bfd_byte
*) zeros
, 4);
3256 sim_pc_set (cpu
, sim_pc_get (cpu
) - 2);
3260 /* Callback from simulator close or read call saying that the pipe at
3261 (reader, writer) is now empty (so the writer can write again, perhaps
3262 leave a waiting state). If there are bytes remaining, they couldn't be
3263 consumed (perhaps due to the pipe closing). */
3266 cris_pipe_empty (host_callback
*cb
,
3271 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3272 SIM_DESC sd
= CPU_STATE (current_cpu_for_cb_callback
);
3273 bfd_byte r10_buf
[4];
3275 = cb
->pipe_buffer
[writer
].size
- cb
->pipe_buffer
[reader
].size
;
3277 /* We need to find the thread that waits for this pipe. */
3278 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3279 if (cpu
->thread_data
[i
].cpu_context
3280 && cpu
->thread_data
[i
].pipe_write_fd
== writer
)
3284 /* Temporarily switch to this cpu context, so we can change the
3285 PC by ordinary calls. */
3287 memcpy (cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3288 &cpu
->cpu_data_placeholder
,
3289 cpu
->thread_cpu_data_size
);
3290 memcpy (&cpu
->cpu_data_placeholder
,
3291 cpu
->thread_data
[i
].cpu_context
,
3292 cpu
->thread_cpu_data_size
);
3294 /* The return value is supposed to contain the number of
3295 written bytes, which is the number of bytes requested and
3296 returned at the write call. You might think the right
3297 thing is to adjust the return-value to be only the
3298 *consumed* number of bytes, but it isn't. We're only
3299 called if the pipe buffer is fully consumed or it is being
3300 closed, possibly with remaining bytes. For the latter
3301 case, the writer is still supposed to see success for
3302 PIPE_BUF bytes (a constant which we happen to know and is
3303 unlikely to change). The return value may also be a
3304 negative number; an error value. This case is covered
3305 because "remaining" is always >= 0. */
3306 (*CPU_REG_FETCH (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3307 retval
= (int) bfd_getl_signed_32 (r10_buf
);
3308 if (retval
- remaining
> TARGET_PIPE_BUF
)
3310 bfd_putl32 (retval
- remaining
, r10_buf
);
3311 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3313 sim_pc_set (cpu
, sim_pc_get (cpu
) + 2);
3314 memcpy (cpu
->thread_data
[i
].cpu_context
,
3315 &cpu
->cpu_data_placeholder
,
3316 cpu
->thread_cpu_data_size
);
3317 memcpy (&cpu
->cpu_data_placeholder
,
3318 cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3319 cpu
->thread_cpu_data_size
);
3320 cpu
->thread_data
[i
].pipe_read_fd
= 0;
3321 cpu
->thread_data
[i
].pipe_write_fd
= 0;
3328 /* We have a simulator-specific notion of time. See TARGET_TIME. */
3331 cris_time (host_callback
*cb ATTRIBUTE_UNUSED
, long *t
)
3333 long retval
= TARGET_TIME (current_cpu_for_cb_callback
);
3339 /* Set target-specific callback data. */
3342 cris_set_callbacks (host_callback
*cb
)
3344 /* Yeargh, have to cast away constness to avoid warnings. */
3345 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_map
;
3346 cb
->errno_map
= (CB_TARGET_DEFS_MAP
*) errno_map
;
3348 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3349 parameter to cb_store_target_endian will make st_size negative.
3350 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3351 *unsigned*, and/or add syntax for signed-ness. */
3352 cb
->stat_map
= stat_map
;
3353 cb
->open_map
= (CB_TARGET_DEFS_MAP
*) open_map
;
3354 cb
->pipe_nonempty
= cris_pipe_nonempty
;
3355 cb
->pipe_empty
= cris_pipe_empty
;
3356 cb
->time
= cris_time
;
3359 /* Process an address exception. */
3362 cris_core_signal (SIM_DESC sd
, SIM_CPU
*current_cpu
, sim_cia cia
,
3363 unsigned int map
, int nr_bytes
, address_word addr
,
3364 transfer_type transfer
, sim_core_signals sig
)
3366 sim_core_signal (sd
, current_cpu
, cia
, map
, nr_bytes
, addr
,