1 /* CRIS exception, interrupt, and trap (EIT) support
2 Copyright (C) 2004-2018 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. */
36 #ifdef HAVE_SYS_PARAM_H
37 #include <sys/param.h>
39 #ifdef HAVE_SYS_STAT_H
42 /* For PATH_MAX, originally. */
47 /* From ld/sysdep.h. */
49 # define SIM_PATHMAX PATH_MAX
52 # define SIM_PATHMAX MAXPATHLEN
54 # define SIM_PATHMAX 1024
58 /* The verbatim values are from asm-cris/unistd.h. */
60 #define TARGET_SYS_exit 1
61 #define TARGET_SYS_read 3
62 #define TARGET_SYS_write 4
63 #define TARGET_SYS_open 5
64 #define TARGET_SYS_close 6
65 #define TARGET_SYS_unlink 10
66 #define TARGET_SYS_time 13
67 #define TARGET_SYS_lseek 19
68 #define TARGET_SYS_getpid 20
69 #define TARGET_SYS_access 33
70 #define TARGET_SYS_kill 37
71 #define TARGET_SYS_rename 38
72 #define TARGET_SYS_pipe 42
73 #define TARGET_SYS_brk 45
74 #define TARGET_SYS_ioctl 54
75 #define TARGET_SYS_fcntl 55
76 #define TARGET_SYS_getppid 64
77 #define TARGET_SYS_setrlimit 75
78 #define TARGET_SYS_gettimeofday 78
79 #define TARGET_SYS_readlink 85
80 #define TARGET_SYS_munmap 91
81 #define TARGET_SYS_truncate 92
82 #define TARGET_SYS_ftruncate 93
83 #define TARGET_SYS_socketcall 102
84 #define TARGET_SYS_stat 106
85 #define TARGET_SYS_fstat 108
86 #define TARGET_SYS_wait4 114
87 #define TARGET_SYS_sigreturn 119
88 #define TARGET_SYS_clone 120
89 #define TARGET_SYS_uname 122
90 #define TARGET_SYS_mprotect 125
91 #define TARGET_SYS_llseek 140
92 #define TARGET_SYS_writev 146
93 #define TARGET_SYS__sysctl 149
94 #define TARGET_SYS_sched_setparam 154
95 #define TARGET_SYS_sched_getparam 155
96 #define TARGET_SYS_sched_setscheduler 156
97 #define TARGET_SYS_sched_getscheduler 157
98 #define TARGET_SYS_sched_yield 158
99 #define TARGET_SYS_sched_get_priority_max 159
100 #define TARGET_SYS_sched_get_priority_min 160
101 #define TARGET_SYS_mremap 163
102 #define TARGET_SYS_poll 168
103 #define TARGET_SYS_rt_sigaction 174
104 #define TARGET_SYS_rt_sigprocmask 175
105 #define TARGET_SYS_rt_sigsuspend 179
106 #define TARGET_SYS_getcwd 183
107 #define TARGET_SYS_ugetrlimit 191
108 #define TARGET_SYS_mmap2 192
109 #define TARGET_SYS_stat64 195
110 #define TARGET_SYS_lstat64 196
111 #define TARGET_SYS_fstat64 197
112 #define TARGET_SYS_geteuid32 201
113 #define TARGET_SYS_getuid32 199
114 #define TARGET_SYS_getegid32 202
115 #define TARGET_SYS_getgid32 200
116 #define TARGET_SYS_fcntl64 221
117 #define TARGET_SYS_set_thread_area 243
118 #define TARGET_SYS_exit_group 252
120 #define TARGET_PROT_READ 0x1
121 #define TARGET_PROT_WRITE 0x2
122 #define TARGET_PROT_EXEC 0x4
123 #define TARGET_PROT_NONE 0x0
125 #define TARGET_MAP_SHARED 0x01
126 #define TARGET_MAP_PRIVATE 0x02
127 #define TARGET_MAP_TYPE 0x0f
128 #define TARGET_MAP_FIXED 0x10
129 #define TARGET_MAP_ANONYMOUS 0x20
130 #define TARGET_MAP_DENYWRITE 0x800
132 #define TARGET_CTL_KERN 1
133 #define TARGET_CTL_VM 2
134 #define TARGET_CTL_NET 3
135 #define TARGET_CTL_PROC 4
136 #define TARGET_CTL_FS 5
137 #define TARGET_CTL_DEBUG 6
138 #define TARGET_CTL_DEV 7
139 #define TARGET_CTL_BUS 8
140 #define TARGET_CTL_ABI 9
142 #define TARGET_CTL_KERN_VERSION 4
145 #define TARGET_MREMAP_MAYMOVE 1
146 #define TARGET_MREMAP_FIXED 2
148 #define TARGET_TCGETS 0x5401
150 #define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
152 /* Seconds since 1970-01-01 to the above date + 10 minutes;
153 'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'. */
154 #define TARGET_EPOCH 1230764410
156 /* Milliseconds since start of run. We use the number of syscalls to
157 avoid introducing noise in the execution time. */
158 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
160 /* Seconds as in time(2). */
161 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
163 #define TARGET_SCHED_OTHER 0
165 #define TARGET_RLIMIT_STACK 3
166 #define TARGET_RLIMIT_NOFILE 7
168 #define SIM_TARGET_MAX_THREADS 64
169 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
171 /* From linux/sched.h. */
172 #define TARGET_CSIGNAL 0x000000ff
173 #define TARGET_CLONE_VM 0x00000100
174 #define TARGET_CLONE_FS 0x00000200
175 #define TARGET_CLONE_FILES 0x00000400
176 #define TARGET_CLONE_SIGHAND 0x00000800
177 #define TARGET_CLONE_PID 0x00001000
178 #define TARGET_CLONE_PTRACE 0x00002000
179 #define TARGET_CLONE_VFORK 0x00004000
180 #define TARGET_CLONE_PARENT 0x00008000
181 #define TARGET_CLONE_THREAD 0x00010000
182 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
184 /* From asm-cris/poll.h. */
185 #define TARGET_POLLIN 1
187 /* From asm-cris/signal.h. */
188 #define TARGET_SIG_BLOCK 0
189 #define TARGET_SIG_UNBLOCK 1
190 #define TARGET_SIG_SETMASK 2
192 #define TARGET_SIG_DFL 0
193 #define TARGET_SIG_IGN 1
194 #define TARGET_SIG_ERR ((USI)-1)
196 #define TARGET_SIGHUP 1
197 #define TARGET_SIGINT 2
198 #define TARGET_SIGQUIT 3
199 #define TARGET_SIGILL 4
200 #define TARGET_SIGTRAP 5
201 #define TARGET_SIGABRT 6
202 #define TARGET_SIGIOT 6
203 #define TARGET_SIGBUS 7
204 #define TARGET_SIGFPE 8
205 #define TARGET_SIGKILL 9
206 #define TARGET_SIGUSR1 10
207 #define TARGET_SIGSEGV 11
208 #define TARGET_SIGUSR2 12
209 #define TARGET_SIGPIPE 13
210 #define TARGET_SIGALRM 14
211 #define TARGET_SIGTERM 15
212 #define TARGET_SIGSTKFLT 16
213 #define TARGET_SIGCHLD 17
214 #define TARGET_SIGCONT 18
215 #define TARGET_SIGSTOP 19
216 #define TARGET_SIGTSTP 20
217 #define TARGET_SIGTTIN 21
218 #define TARGET_SIGTTOU 22
219 #define TARGET_SIGURG 23
220 #define TARGET_SIGXCPU 24
221 #define TARGET_SIGXFSZ 25
222 #define TARGET_SIGVTALRM 26
223 #define TARGET_SIGPROF 27
224 #define TARGET_SIGWINCH 28
225 #define TARGET_SIGIO 29
226 #define TARGET_SIGPOLL SIGIO
227 /* Actually commented out in the kernel header. */
228 #define TARGET_SIGLOST 29
229 #define TARGET_SIGPWR 30
230 #define TARGET_SIGSYS 31
232 /* From include/asm-cris/signal.h. */
233 #define TARGET_SA_NOCLDSTOP 0x00000001
234 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
235 #define TARGET_SA_SIGINFO 0x00000004
236 #define TARGET_SA_ONSTACK 0x08000000
237 #define TARGET_SA_RESTART 0x10000000
238 #define TARGET_SA_NODEFER 0x40000000
239 #define TARGET_SA_RESETHAND 0x80000000
240 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
241 #define TARGET_SA_RESTORER 0x04000000
243 /* From linux/wait.h. */
244 #define TARGET_WNOHANG 1
245 #define TARGET_WUNTRACED 2
246 #define TARGET___WNOTHREAD 0x20000000
247 #define TARGET___WALL 0x40000000
248 #define TARGET___WCLONE 0x80000000
250 /* From linux/limits.h. */
251 #define TARGET_PIPE_BUF 4096
254 #define TARGET_R_OK 4
255 #define TARGET_W_OK 2
256 #define TARGET_X_OK 1
257 #define TARGET_F_OK 0
259 static const char stat_map
[] =
260 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
261 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
262 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
265 static const CB_TARGET_DEFS_MAP syscall_map
[] =
267 { "open", CB_SYS_open
, TARGET_SYS_open
},
268 { "close", CB_SYS_close
, TARGET_SYS_close
},
269 { "read", CB_SYS_read
, TARGET_SYS_read
},
270 { "write", CB_SYS_write
, TARGET_SYS_write
},
271 { "lseek", CB_SYS_lseek
, TARGET_SYS_lseek
},
272 { "unlink", CB_SYS_unlink
, TARGET_SYS_unlink
},
273 { "getpid", CB_SYS_getpid
, TARGET_SYS_getpid
},
274 { "fstat", CB_SYS_fstat
, TARGET_SYS_fstat64
},
275 { "lstat", CB_SYS_lstat
, TARGET_SYS_lstat64
},
276 { "stat", CB_SYS_stat
, TARGET_SYS_stat64
},
277 { "pipe", CB_SYS_pipe
, TARGET_SYS_pipe
},
278 { "rename", CB_SYS_rename
, TARGET_SYS_rename
},
279 { "truncate", CB_SYS_truncate
, TARGET_SYS_truncate
},
280 { "ftruncate", CB_SYS_ftruncate
, TARGET_SYS_ftruncate
},
284 /* An older, 32-bit-only stat mapping. */
285 static const char stat32_map
[] =
286 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
287 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
288 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
290 /* Map for calls using the 32-bit struct stat. Primarily used by the
291 newlib Linux mapping. */
292 static const CB_TARGET_DEFS_MAP syscall_stat32_map
[] =
294 { "fstat", CB_SYS_fstat
, TARGET_SYS_fstat
},
295 { "stat", CB_SYS_stat
, TARGET_SYS_stat
},
299 /* Giving the true value for the running sim process will lead to
300 non-time-invariant behavior. */
301 #define TARGET_PID 42
303 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
304 we did, we'd still don't get a register number with the "16" offset. */
305 #define TARGET_SRP_REGNUM (16+11)
307 /* Extracted by applying
308 awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
309 on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
310 adjusting the synonyms. */
312 static const CB_TARGET_DEFS_MAP errno_map
[] =
315 { "EPERM", EPERM
, 1 },
318 { "ENOENT", ENOENT
, 2 },
321 { "ESRCH", ESRCH
, 3 },
324 { "EINTR", EINTR
, 4 },
330 { "ENXIO", ENXIO
, 6 },
333 { "E2BIG", E2BIG
, 7 },
336 { "ENOEXEC", ENOEXEC
, 8 },
339 { "EBADF", EBADF
, 9 },
342 { "ECHILD", ECHILD
, 10 },
345 { "EAGAIN", EAGAIN
, 11 },
348 { "ENOMEM", ENOMEM
, 12 },
351 { "EACCES", EACCES
, 13 },
354 { "EFAULT", EFAULT
, 14 },
357 { "ENOTBLK", ENOTBLK
, 15 },
360 { "EBUSY", EBUSY
, 16 },
363 { "EEXIST", EEXIST
, 17 },
366 { "EXDEV", EXDEV
, 18 },
369 { "ENODEV", ENODEV
, 19 },
372 { "ENOTDIR", ENOTDIR
, 20 },
375 { "EISDIR", EISDIR
, 21 },
378 { "EINVAL", EINVAL
, 22 },
381 { "ENFILE", ENFILE
, 23 },
384 { "EMFILE", EMFILE
, 24 },
387 { "ENOTTY", ENOTTY
, 25 },
390 { "ETXTBSY", ETXTBSY
, 26 },
393 { "EFBIG", EFBIG
, 27 },
396 { "ENOSPC", ENOSPC
, 28 },
399 { "ESPIPE", ESPIPE
, 29 },
402 { "EROFS", EROFS
, 30 },
405 { "EMLINK", EMLINK
, 31 },
408 { "EPIPE", EPIPE
, 32 },
411 { "EDOM", EDOM
, 33 },
414 { "ERANGE", ERANGE
, 34 },
417 { "EDEADLK", EDEADLK
, 35 },
420 { "ENAMETOOLONG", ENAMETOOLONG
, 36 },
423 { "ENOLCK", ENOLCK
, 37 },
426 { "ENOSYS", ENOSYS
, 38 },
429 { "ENOTEMPTY", ENOTEMPTY
, 39 },
432 { "ELOOP", ELOOP
, 40 },
435 { "EWOULDBLOCK", EWOULDBLOCK
, 11 },
438 { "ENOMSG", ENOMSG
, 42 },
441 { "EIDRM", EIDRM
, 43 },
444 { "ECHRNG", ECHRNG
, 44 },
447 { "EL2NSYNC", EL2NSYNC
, 45 },
450 { "EL3HLT", EL3HLT
, 46 },
453 { "EL3RST", EL3RST
, 47 },
456 { "ELNRNG", ELNRNG
, 48 },
459 { "EUNATCH", EUNATCH
, 49 },
462 { "ENOCSI", ENOCSI
, 50 },
465 { "EL2HLT", EL2HLT
, 51 },
468 { "EBADE", EBADE
, 52 },
471 { "EBADR", EBADR
, 53 },
474 { "EXFULL", EXFULL
, 54 },
477 { "ENOANO", ENOANO
, 55 },
480 { "EBADRQC", EBADRQC
, 56 },
483 { "EBADSLT", EBADSLT
, 57 },
486 { "EDEADLOCK", EDEADLOCK
, 35 },
489 { "EBFONT", EBFONT
, 59 },
492 { "ENOSTR", ENOSTR
, 60 },
495 { "ENODATA", ENODATA
, 61 },
498 { "ETIME", ETIME
, 62 },
501 { "ENOSR", ENOSR
, 63 },
504 { "ENONET", ENONET
, 64 },
507 { "ENOPKG", ENOPKG
, 65 },
510 { "EREMOTE", EREMOTE
, 66 },
513 { "ENOLINK", ENOLINK
, 67 },
516 { "EADV", EADV
, 68 },
519 { "ESRMNT", ESRMNT
, 69 },
522 { "ECOMM", ECOMM
, 70 },
525 { "EPROTO", EPROTO
, 71 },
528 { "EMULTIHOP", EMULTIHOP
, 72 },
531 { "EDOTDOT", EDOTDOT
, 73 },
534 { "EBADMSG", EBADMSG
, 74 },
537 { "EOVERFLOW", EOVERFLOW
, 75 },
540 { "ENOTUNIQ", ENOTUNIQ
, 76 },
543 { "EBADFD", EBADFD
, 77 },
546 { "EREMCHG", EREMCHG
, 78 },
549 { "ELIBACC", ELIBACC
, 79 },
552 { "ELIBBAD", ELIBBAD
, 80 },
555 { "ELIBSCN", ELIBSCN
, 81 },
558 { "ELIBMAX", ELIBMAX
, 82 },
561 { "ELIBEXEC", ELIBEXEC
, 83 },
564 { "EILSEQ", EILSEQ
, 84 },
567 { "ERESTART", ERESTART
, 85 },
570 { "ESTRPIPE", ESTRPIPE
, 86 },
573 { "EUSERS", EUSERS
, 87 },
576 { "ENOTSOCK", ENOTSOCK
, 88 },
579 { "EDESTADDRREQ", EDESTADDRREQ
, 89 },
582 { "EMSGSIZE", EMSGSIZE
, 90 },
585 { "EPROTOTYPE", EPROTOTYPE
, 91 },
588 { "ENOPROTOOPT", ENOPROTOOPT
, 92 },
590 #ifdef EPROTONOSUPPORT
591 { "EPROTONOSUPPORT", EPROTONOSUPPORT
, 93 },
593 #ifdef ESOCKTNOSUPPORT
594 { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT
, 94 },
597 { "EOPNOTSUPP", EOPNOTSUPP
, 95 },
600 { "EPFNOSUPPORT", EPFNOSUPPORT
, 96 },
603 { "EAFNOSUPPORT", EAFNOSUPPORT
, 97 },
606 { "EADDRINUSE", EADDRINUSE
, 98 },
609 { "EADDRNOTAVAIL", EADDRNOTAVAIL
, 99 },
612 { "ENETDOWN", ENETDOWN
, 100 },
615 { "ENETUNREACH", ENETUNREACH
, 101 },
618 { "ENETRESET", ENETRESET
, 102 },
621 { "ECONNABORTED", ECONNABORTED
, 103 },
624 { "ECONNRESET", ECONNRESET
, 104 },
627 { "ENOBUFS", ENOBUFS
, 105 },
630 { "EISCONN", EISCONN
, 106 },
633 { "ENOTCONN", ENOTCONN
, 107 },
636 { "ESHUTDOWN", ESHUTDOWN
, 108 },
639 { "ETOOMANYREFS", ETOOMANYREFS
, 109 },
642 { "ETIMEDOUT", ETIMEDOUT
, 110 },
645 { "ECONNREFUSED", ECONNREFUSED
, 111 },
648 { "EHOSTDOWN", EHOSTDOWN
, 112 },
651 { "EHOSTUNREACH", EHOSTUNREACH
, 113 },
654 { "EALREADY", EALREADY
, 114 },
657 { "EINPROGRESS", EINPROGRESS
, 115 },
660 { "ESTALE", ESTALE
, 116 },
663 { "EUCLEAN", EUCLEAN
, 117 },
666 { "ENOTNAM", ENOTNAM
, 118 },
669 { "ENAVAIL", ENAVAIL
, 119 },
672 { "EISNAM", EISNAM
, 120 },
675 { "EREMOTEIO", EREMOTEIO
, 121 },
678 { "EDQUOT", EDQUOT
, 122 },
681 { "ENOMEDIUM", ENOMEDIUM
, 123 },
684 { "EMEDIUMTYPE", EMEDIUMTYPE
, 124 },
689 /* Extracted by applying
690 perl -ne 'if ($_ =~ /^#define/) { split;
691 printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
692 $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
693 on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
694 installation and removing synonyms and unnecessary items. Don't
695 forget the end-marker. */
697 /* These we treat specially, as they're used in the fcntl F_GETFL
698 syscall. For consistency, open_map is also manually edited to use
700 #define TARGET_O_ACCMODE 0x3
701 #define TARGET_O_RDONLY 0x0
702 #define TARGET_O_WRONLY 0x1
704 static const CB_TARGET_DEFS_MAP open_map
[] = {
706 { "O_ACCMODE", O_ACCMODE
, TARGET_O_ACCMODE
},
709 { "O_RDONLY", O_RDONLY
, TARGET_O_RDONLY
},
712 { "O_WRONLY", O_WRONLY
, TARGET_O_WRONLY
},
715 { "O_RDWR", O_RDWR
, 0x2 },
718 { "O_CREAT", O_CREAT
, 0x40 },
721 { "O_EXCL", O_EXCL
, 0x80 },
724 { "O_NOCTTY", O_NOCTTY
, 0x100 },
727 { "O_TRUNC", O_TRUNC
, 0x200 },
730 { "O_APPEND", O_APPEND
, 0x400 },
733 { "O_NONBLOCK", O_NONBLOCK
, 0x800 },
736 { "O_NDELAY", O_NDELAY
, 0x0 },
739 { "O_SYNC", O_SYNC
, 0x1000 },
742 { "FASYNC", FASYNC
, 0x2000 },
745 { "O_DIRECT", O_DIRECT
, 0x4000 },
748 { "O_LARGEFILE", O_LARGEFILE
, 0x8000 },
751 { "O_DIRECTORY", O_DIRECTORY
, 0x10000 },
754 { "O_NOFOLLOW", O_NOFOLLOW
, 0x20000 },
759 /* Let's be less drastic and more traceable. FIXME: mark as noreturn. */
761 sim_io_error (sd, "simulator unhandled condition at %s:%d", \
762 __FUNCTION__, __LINE__)
764 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
765 static SIM_CPU
*current_cpu_for_cb_callback
;
767 static USI
create_map (SIM_DESC
, struct cris_sim_mmapped_page
**,
769 static USI
unmap_pages (SIM_DESC
, struct cris_sim_mmapped_page
**,
771 static USI
is_mapped (SIM_DESC
, struct cris_sim_mmapped_page
**,
773 static void dump_statistics (SIM_CPU
*current_cpu
);
774 static void make_first_thread (SIM_CPU
*current_cpu
);
776 /* When we risk running self-modified code (as in trampolines), this is
777 called from special-case insns. The silicon CRIS CPU:s have enough
778 cache snooping implemented making this a simulator-only issue. Tests:
779 gcc.c-torture/execute/931002-1.c execution, -O3 -g
780 gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
783 cris_flush_simulator_decode_cache (SIM_CPU
*current_cpu
,
784 USI pc ATTRIBUTE_UNUSED
)
786 SIM_DESC sd
= CPU_STATE (current_cpu
);
789 if (USING_SCACHE_P (sd
))
790 scache_flush_cpu (current_cpu
);
794 /* Output statistics at the end of a run. */
796 dump_statistics (SIM_CPU
*current_cpu
)
798 SIM_DESC sd
= CPU_STATE (current_cpu
);
799 CRIS_MISC_PROFILE
*profp
800 = CPU_CRIS_MISC_PROFILE (current_cpu
);
801 unsigned64 total
= profp
->basic_cycle_count
;
802 const char *textmsg
= "Basic clock cycles, total @: %llu\n";
804 /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
805 what's included in the "total" count only. */
806 switch (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
807 & FLAG_CRIS_MISC_PROFILE_ALL
)
809 case FLAG_CRIS_MISC_PROFILE_SIMPLE
:
812 case (FLAG_CRIS_MISC_PROFILE_UNALIGNED
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
814 = "Clock cycles including stall cycles for unaligned accesses @: %llu\n";
815 total
+= profp
->unaligned_mem_dword_count
;
818 case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
| FLAG_CRIS_MISC_PROFILE_SIMPLE
):
819 textmsg
= "Schedulable clock cycles, total @: %llu\n";
821 += (profp
->memsrc_stall_count
822 + profp
->memraw_stall_count
823 + profp
->movemsrc_stall_count
824 + profp
->movemdst_stall_count
825 + profp
->mulsrc_stall_count
826 + profp
->jumpsrc_stall_count
827 + profp
->unaligned_mem_dword_count
);
830 case FLAG_CRIS_MISC_PROFILE_ALL
:
831 textmsg
= "All accounted clock cycles, total @: %llu\n";
833 += (profp
->memsrc_stall_count
834 + profp
->memraw_stall_count
835 + profp
->movemsrc_stall_count
836 + profp
->movemdst_stall_count
837 + profp
->movemaddr_stall_count
838 + profp
->mulsrc_stall_count
839 + profp
->jumpsrc_stall_count
840 + profp
->branch_stall_count
841 + profp
->jumptarget_stall_count
842 + profp
->unaligned_mem_dword_count
);
849 "Internal inconsistency at %s:%d",
851 sim_engine_halt (sd
, current_cpu
, NULL
, 0,
852 sim_stopped
, SIM_SIGILL
);
855 /* Historically, these messages have gone to stderr, so we'll keep it
856 that way. It's also easier to then tell it from normal program
857 output. FIXME: Add redirect option like "run -e file". */
858 sim_io_eprintf (sd
, textmsg
, total
);
860 /* For v32, unaligned_mem_dword_count should always be 0. For
861 v10, memsrc_stall_count should always be 0. */
862 sim_io_eprintf (sd
, "Memory source stall cycles: %llu\n",
863 (unsigned long long) (profp
->memsrc_stall_count
864 + profp
->unaligned_mem_dword_count
));
865 sim_io_eprintf (sd
, "Memory read-after-write stall cycles: %llu\n",
866 (unsigned long long) profp
->memraw_stall_count
);
867 sim_io_eprintf (sd
, "Movem source stall cycles: %llu\n",
868 (unsigned long long) profp
->movemsrc_stall_count
);
869 sim_io_eprintf (sd
, "Movem destination stall cycles: %llu\n",
870 (unsigned long long) profp
->movemdst_stall_count
);
871 sim_io_eprintf (sd
, "Movem address stall cycles: %llu\n",
872 (unsigned long long) profp
->movemaddr_stall_count
);
873 sim_io_eprintf (sd
, "Multiplication source stall cycles: %llu\n",
874 (unsigned long long) profp
->mulsrc_stall_count
);
875 sim_io_eprintf (sd
, "Jump source stall cycles: %llu\n",
876 (unsigned long long) profp
->jumpsrc_stall_count
);
877 sim_io_eprintf (sd
, "Branch misprediction stall cycles: %llu\n",
878 (unsigned long long) profp
->branch_stall_count
);
879 sim_io_eprintf (sd
, "Jump target stall cycles: %llu\n",
880 (unsigned long long) profp
->jumptarget_stall_count
);
883 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
884 Return 1 if a overlap detected, 0 otherwise. */
887 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED
,
888 struct cris_sim_mmapped_page
**rootp
,
891 struct cris_sim_mmapped_page
*mapp
;
893 if (len
== 0 || (len
& 8191))
896 /* Iterate over the reverse-address sorted pages until we find a page in
897 or lower than the checked area. */
898 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
899 if (mapp
->addr
< addr
+ len
&& mapp
->addr
>= addr
)
905 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
906 Return 1 if the whole area is mapped, 0 otherwise. */
909 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED
,
910 struct cris_sim_mmapped_page
**rootp
,
913 struct cris_sim_mmapped_page
*mapp
;
915 if (len
== 0 || (len
& 8191))
918 /* Iterate over the reverse-address sorted pages until we find a page
919 lower than the checked area. */
920 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
>= addr
; mapp
= mapp
->prev
)
921 if (addr
== mapp
->addr
&& len
== 8192)
923 else if (addr
+ len
> mapp
->addr
)
929 /* Debug helper; to be run from gdb. */
932 cris_dump_map (SIM_CPU
*current_cpu
)
934 struct cris_sim_mmapped_page
*mapp
;
937 for (mapp
= current_cpu
->highest_mmapped_page
,
938 start
= mapp
== NULL
? 0 : mapp
->addr
+ 8192,
939 end
= mapp
== NULL
? 0 : mapp
->addr
+ 8191;
943 if (mapp
->addr
!= start
- 8192)
945 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
946 end
= mapp
->addr
+ 8191;
952 if (current_cpu
->highest_mmapped_page
!= NULL
)
953 sim_io_eprintf (CPU_STATE (current_cpu
), "0x%x..0x%x\n", start
, end
);
956 /* Create mmapped memory. ADDR is -1 if any address will do. Caller
957 must make sure that the address isn't already mapped. */
960 create_map (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
963 struct cris_sim_mmapped_page
*mapp
;
964 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
965 USI new_addr
= 0x40000000;
967 if (addr
!= (USI
) -1)
969 else if (*rootp
&& rootp
[0]->addr
>= new_addr
)
970 new_addr
= rootp
[0]->addr
+ 8192;
977 /* Which is better: return an error for this, or just round it up? */
980 /* Do a recursive call for each page in the request. */
981 for (page_addr
= new_addr
; len
!= 0; page_addr
+= 8192, len
-= 8192)
982 if (create_map (sd
, rootp
, page_addr
, 8192) >= (USI
) -8191)
989 mapp
!= NULL
&& mapp
->addr
> new_addr
;
991 higher_prevp
= &mapp
->prev
;
993 /* Assert for consistency that we don't create duplicate maps. */
994 if (is_mapped (sd
, rootp
, new_addr
, len
))
997 /* Allocate the new page, on the next higher page from the last one
998 allocated, and link in the new descriptor before previous ones. */
999 mapp
= malloc (sizeof (*mapp
));
1002 return (USI
) -ENOMEM
;
1004 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1008 mapp
->addr
= new_addr
;
1009 mapp
->prev
= *higher_prevp
;
1010 *higher_prevp
= mapp
;
1015 /* Unmap one or more pages. */
1018 unmap_pages (SIM_DESC sd
, struct cris_sim_mmapped_page
**rootp
, USI addr
,
1021 struct cris_sim_mmapped_page
*mapp
;
1022 struct cris_sim_mmapped_page
**higher_prevp
= rootp
;
1030 /* Which is better: return an error for this, or just round it up? */
1033 /* Loop backwards to make each call is O(1) over the number of pages
1034 allocated, if we're unmapping from the high end of the pages. */
1035 for (page_addr
= addr
+ len
- 8192;
1038 if (unmap_pages (sd
, rootp
, page_addr
, 8192))
1041 if (unmap_pages (sd
, rootp
, addr
, 8192))
1047 for (mapp
= *rootp
; mapp
!= NULL
&& mapp
->addr
> addr
; mapp
= mapp
->prev
)
1048 higher_prevp
= &mapp
->prev
;
1050 if (mapp
== NULL
|| mapp
->addr
!= addr
)
1053 *higher_prevp
= mapp
->prev
;
1054 sim_core_detach (sd
, NULL
, 0, 0, addr
);
1059 /* The semantic code invokes this for illegal (unrecognized) instructions. */
1062 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC vpc
)
1064 SIM_DESC sd
= CPU_STATE (current_cpu
);
1066 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
1070 /* Handlers from the CGEN description that should not be called. */
1073 cris_bmod_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1074 UINT srcreg ATTRIBUTE_UNUSED
,
1075 USI dstreg ATTRIBUTE_UNUSED
)
1077 SIM_DESC sd
= CPU_STATE (current_cpu
);
1082 h_supr_set_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1083 UINT index ATTRIBUTE_UNUSED
,
1084 USI page ATTRIBUTE_UNUSED
,
1085 USI newval ATTRIBUTE_UNUSED
)
1087 SIM_DESC sd
= CPU_STATE (current_cpu
);
1092 h_supr_get_handler (SIM_CPU
*current_cpu ATTRIBUTE_UNUSED
,
1093 UINT index ATTRIBUTE_UNUSED
,
1094 USI page ATTRIBUTE_UNUSED
)
1096 SIM_DESC sd
= CPU_STATE (current_cpu
);
1100 /* Swap one context for another. */
1103 schedule (SIM_CPU
*current_cpu
, int next
)
1105 /* Need to mark context-switches in the trace output. */
1106 if ((CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1107 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE
))
1108 cris_trace_printf (CPU_STATE (current_cpu
), current_cpu
,
1111 /* Copy the current context (if there is one) to its slot. */
1112 if (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
)
1113 memcpy (current_cpu
->thread_data
[current_cpu
->threadno
].cpu_context
,
1114 ¤t_cpu
->cpu_data_placeholder
,
1115 current_cpu
->thread_cpu_data_size
);
1117 /* Copy the new context from its slot. */
1118 memcpy (¤t_cpu
->cpu_data_placeholder
,
1119 current_cpu
->thread_data
[next
].cpu_context
,
1120 current_cpu
->thread_cpu_data_size
);
1122 /* Update needed stuff to indicate the new context. */
1123 current_cpu
->threadno
= next
;
1125 /* Handle pending signals. */
1126 if (current_cpu
->thread_data
[next
].sigpending
1127 /* We don't run nested signal handlers. This means that pause(2)
1128 and sigsuspend(2) do not work in sighandlers, but that
1129 shouldn't be too hard a restriction. It also greatly
1130 simplifies the code. */
1131 && current_cpu
->thread_data
[next
].cpu_context_atsignal
== NULL
)
1135 /* See if there's really a pending, non-blocked handler. We don't
1136 queue signals, so just use the first one in ascending order. */
1137 for (sig
= 0; sig
< 64; sig
++)
1138 if (current_cpu
->thread_data
[next
].sigdata
[sig
].pending
1139 && !current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
)
1145 USI pc
= sim_pc_get (current_cpu
);
1147 /* It's simpler to save the CPU context inside the simulator
1148 than on the stack. */
1149 current_cpu
->thread_data
[next
].cpu_context_atsignal
1151 ->make_thread_cpu_data
) (current_cpu
,
1152 current_cpu
->thread_data
[next
]
1155 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1156 sp
= bfd_getl32 (regbuf
);
1158 /* Make sure we have an aligned stack. */
1161 /* Make room for the signal frame, aligned. FIXME: Check that
1162 the memory exists, map it in if absent. (BTW, should also
1163 implement on-access automatic stack allocation). */
1166 /* This isn't the same signal frame as the kernel uses, because
1167 we don't want to bother getting all registers on and off the
1170 /* First, we store the currently blocked signals. */
1172 for (i
= 0; i
< 32; i
++)
1174 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 1].blocked
<< i
;
1175 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
, blocked
);
1177 for (i
= 0; i
< 31; i
++)
1179 |= current_cpu
->thread_data
[next
].sigdata
[i
+ 33].blocked
<< i
;
1180 sim_core_write_aligned_4 (current_cpu
, pc
, 0, sp
+ 4, blocked
);
1182 /* Then, the actual instructions. This is CPU-specific, but we
1183 use instructions from the common subset for v10 and v32 which
1184 should be safe for the time being but could be parametrized
1186 /* MOVU.W [PC+],R9. */
1187 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 8, 0x9c5f);
1188 /* .WORD TARGET_SYS_sigreturn. */
1189 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 10,
1190 TARGET_SYS_sigreturn
);
1192 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 12, 0xe93d);
1194 /* NOP (on v32; it's SETF on v10, but is the correct compatible
1195 instruction. Still, it doesn't matter because v10 has no
1196 delay slot for BREAK so it will not be executed). */
1197 sim_core_write_aligned_2 (current_cpu
, pc
, 0, sp
+ 16, 0x05b0);
1199 /* Modify registers to hold the right values for the sighandler
1200 context: updated stackpointer and return address pointing to
1201 the sigreturn stub. */
1202 bfd_putl32 (sp
, regbuf
);
1203 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_SP
, regbuf
, 4);
1204 bfd_putl32 (sp
+ 8, regbuf
);
1205 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, TARGET_SRP_REGNUM
,
1208 current_cpu
->thread_data
[next
].sigdata
[sig
].pending
= 0;
1210 /* Block this signal (for the duration of the sighandler). */
1211 current_cpu
->thread_data
[next
].sigdata
[sig
].blocked
= 1;
1213 sim_pc_set (current_cpu
, current_cpu
->sighandler
[sig
]);
1214 bfd_putl32 (sig
, regbuf
);
1215 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
,
1218 /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1219 needed all this for, specifies a SA_SIGINFO call but treats it
1220 like an ordinary sighandler; only the signal number argument is
1221 inspected. To make future need to implement SA_SIGINFO
1222 correctly possible, we set the siginfo argument register to a
1223 magic (hopefully non-address) number. (NB: then, you should
1224 just need to pass the siginfo argument; it seems you probably
1225 don't need to implement the specific rt_sigreturn.) */
1226 bfd_putl32 (0xbad5161f, regbuf
);
1227 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R11
,
1230 /* The third argument is unused and the kernel sets it to 0. */
1231 bfd_putl32 (0, regbuf
);
1232 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R12
,
1237 /* No, there actually was no pending signal for this thread. Reset
1239 current_cpu
->thread_data
[next
].sigpending
= 0;
1243 /* Reschedule the simplest possible way until something else is absolutely
1245 - A. Find the next process (round-robin) that doesn't have at_syscall
1247 - B. If there is none, just run the next process, round-robin.
1248 - Clear at_syscall for the current process. */
1251 reschedule (SIM_CPU
*current_cpu
)
1253 SIM_DESC sd
= CPU_STATE (current_cpu
);
1256 /* Iterate over all thread slots, because after a few thread creations
1257 and exits, we don't know where the live ones are. */
1258 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1259 i
!= current_cpu
->threadno
;
1260 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1261 if (current_cpu
->thread_data
[i
].cpu_context
1262 && current_cpu
->thread_data
[i
].at_syscall
== 0)
1264 schedule (current_cpu
, i
);
1268 /* Pick any next live thread. */
1269 for (i
= (current_cpu
->threadno
+ 1) % SIM_TARGET_MAX_THREADS
;
1270 i
!= current_cpu
->threadno
;
1271 i
= (i
+ 1) % SIM_TARGET_MAX_THREADS
)
1272 if (current_cpu
->thread_data
[i
].cpu_context
)
1274 schedule (current_cpu
, i
);
1278 /* More than one live thread, but we couldn't find the next one? */
1282 /* Set up everything to receive (or IGN) an incoming signal to the
1286 deliver_signal (SIM_CPU
*current_cpu
, int sig
, unsigned int pid
)
1289 USI pc
= sim_pc_get (current_cpu
);
1291 /* Find the thread index of the pid. */
1292 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
1293 /* Apparently it's ok to send signals to zombies (so a check for
1294 current_cpu->thread_data[i].cpu_context != NULL would be
1296 if (current_cpu
->thread_data
[i
].threadid
== pid
- TARGET_PID
)
1299 switch (current_cpu
->sighandler
[sig
])
1301 case TARGET_SIG_DFL
:
1304 /* The following according to the glibc
1305 documentation. (The kernel code has non-obvious
1306 execution paths.) */
1309 case TARGET_SIGSEGV
:
1311 case TARGET_SIGABRT
:
1312 case TARGET_SIGTRAP
:
1315 case TARGET_SIGTERM
:
1317 case TARGET_SIGQUIT
:
1318 case TARGET_SIGKILL
:
1321 case TARGET_SIGALRM
:
1322 case TARGET_SIGVTALRM
:
1323 case TARGET_SIGPROF
:
1324 case TARGET_SIGSTOP
:
1326 case TARGET_SIGPIPE
:
1327 case TARGET_SIGLOST
:
1328 case TARGET_SIGXCPU
:
1329 case TARGET_SIGXFSZ
:
1330 case TARGET_SIGUSR1
:
1331 case TARGET_SIGUSR2
:
1332 sim_io_eprintf (CPU_STATE (current_cpu
),
1333 "Exiting pid %d due to signal %d\n",
1335 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1336 NULL
, pc
, sim_stopped
,
1337 sig
== TARGET_SIGABRT
1338 ? SIM_SIGABRT
: SIM_SIGILL
);
1341 /* The default for all other signals is to be ignored. */
1346 case TARGET_SIG_IGN
:
1349 case TARGET_SIGKILL
:
1350 case TARGET_SIGSTOP
:
1351 /* Can't ignore these signals. */
1352 sim_io_eprintf (CPU_STATE (current_cpu
),
1353 "Exiting pid %d due to signal %d\n",
1355 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
,
1356 NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1365 /* Mark the signal as pending, making schedule () check
1366 closer. The signal will be handled when the thread is
1367 scheduled and the signal is unblocked. */
1368 current_cpu
->thread_data
[i
].sigdata
[sig
].pending
= 1;
1369 current_cpu
->thread_data
[i
].sigpending
= 1;
1374 sim_io_eprintf (CPU_STATE (current_cpu
),
1375 "Unimplemented signal: %d\n", sig
);
1376 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
1377 sim_stopped
, SIM_SIGILL
);
1382 -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu
)),
1386 /* Make the vector and the first item, the main thread. */
1389 make_first_thread (SIM_CPU
*current_cpu
)
1391 SIM_DESC sd
= CPU_STATE (current_cpu
);
1392 current_cpu
->thread_data
1394 SIM_TARGET_MAX_THREADS
1395 * sizeof (current_cpu
->thread_data
[0]));
1396 current_cpu
->thread_data
[0].cpu_context
1397 = (*current_cpu
->make_thread_cpu_data
) (current_cpu
,
1399 ->cpu_data_placeholder
);
1400 current_cpu
->thread_data
[0].parent_threadid
= -1;
1402 /* For good measure. */
1403 if (TARGET_SIG_DFL
!= 0)
1407 /* Handle unknown system calls. Returns (if it does) the syscall
1411 cris_unknown_syscall (SIM_CPU
*current_cpu
, USI pc
, char *s
, ...)
1413 SIM_DESC sd
= CPU_STATE (current_cpu
);
1414 host_callback
*cb
= STATE_CALLBACK (sd
);
1416 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
1417 || cris_unknown_syscall_action
== CRIS_USYSC_MSG_ENOSYS
)
1422 sim_io_evprintf (sd
, s
, ap
);
1425 if (cris_unknown_syscall_action
== CRIS_USYSC_MSG_STOP
)
1426 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1429 return -cb_host_to_target_errno (cb
, ENOSYS
);
1432 /* Main function: the handler of the "break 13" syscall insn. */
1435 cris_break_13_handler (SIM_CPU
*current_cpu
, USI callnum
, USI arg1
,
1436 USI arg2
, USI arg3
, USI arg4
, USI arg5
, USI arg6
,
1440 SIM_DESC sd
= CPU_STATE (current_cpu
);
1441 host_callback
*cb
= STATE_CALLBACK (sd
);
1443 int threadno
= current_cpu
->threadno
;
1445 current_cpu
->syscalls
++;
1447 CB_SYSCALL_INIT (&s
);
1453 /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need
1454 to sign-extend the lseek offset to be passed as a signed number,
1455 else we'll truncate it to something > 2GB on hosts where sizeof
1456 long > sizeof USI. We avoid doing it for all syscalls, as arg2 is
1457 e.g. an address for some syscalls. */
1458 if (callnum
== TARGET_SYS_lseek
)
1461 if (callnum
== TARGET_SYS_exit_group
1462 || (callnum
== TARGET_SYS_exit
&& current_cpu
->m1threads
== 0))
1464 if (CPU_CRIS_MISC_PROFILE (current_cpu
)->flags
1465 & FLAG_CRIS_MISC_PROFILE_ALL
)
1466 dump_statistics (current_cpu
);
1467 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
1471 s
.p2
= (PTR
) current_cpu
;
1472 s
.read_mem
= sim_syscall_read_mem
;
1473 s
.write_mem
= sim_syscall_write_mem
;
1475 current_cpu_for_cb_callback
= current_cpu
;
1477 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1480 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
1482 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
1485 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
1487 if (s
.errcode
!= 0 && s
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
1489 /* If the generic simulator call said ENOSYS, then let's try the
1490 ones we know ourselves.
1492 The convention is to provide *very limited* functionality on an
1493 as-needed basis, only what's covered by the test-suite, tests
1494 added when functionality changes and abort with a descriptive
1495 message for *everything* else. Where there's no test-case, we
1500 /* It's a pretty safe bet that the "old setup() system call"
1501 number will not be re-used; we can't say the same for higher
1502 numbers. We treat this simulator-generated call as "wait
1503 forever"; we re-run this insn. The wait is ended by a
1504 callback. Sanity check that this is the reason we got
1506 if (current_cpu
->thread_data
== NULL
1507 || (current_cpu
->thread_data
[threadno
].pipe_write_fd
== 0))
1508 goto unimplemented_syscall
;
1510 sim_pc_set (current_cpu
, pc
);
1514 case TARGET_SYS_fcntl64
:
1515 case TARGET_SYS_fcntl
:
1520 Glibc checks stdin, stdout and stderr fd:s for
1521 close-on-exec security sanity. We just need to provide a
1522 OK return value. If we really need to have a
1523 close-on-exec flag true, we could just do a real fcntl
1529 /* F_SETFD. Just ignore attempts to set the close-on-exec
1535 /* F_GETFL. Check for the special case for open+fdopen. */
1536 if (current_cpu
->last_syscall
== TARGET_SYS_open
1537 && arg1
== current_cpu
->last_open_fd
)
1539 retval
= current_cpu
->last_open_flags
& TARGET_O_ACCMODE
;
1544 /* Because we can't freopen fd:s 0, 1, 2 to mean
1545 something else than stdin, stdout and stderr
1546 (sim/common/syscall.c:cb_syscall special cases fd
1547 0, 1 and 2), we know what flags that we can
1548 sanely return for these fd:s. */
1549 retval
= TARGET_O_RDONLY
;
1552 else if (arg1
== 1 || arg1
== 2)
1554 retval
= TARGET_O_WRONLY
;
1559 /* Nothing else is implemented. */
1561 = cris_unknown_syscall (current_cpu
, pc
,
1562 "Unimplemented %s syscall "
1563 "(fd: 0x%lx: cmd: 0x%lx arg: "
1565 callnum
== TARGET_SYS_fcntl
1566 ? "fcntl" : "fcntl64",
1567 (unsigned long) (USI
) arg1
,
1568 (unsigned long) (USI
) arg2
,
1569 (unsigned long) (USI
) arg3
);
1574 case TARGET_SYS_uname
:
1576 /* Fill in a few constants to appease glibc. */
1577 static char sim_utsname
[6][65] =
1583 "cris", /* Overwritten below. */
1587 /* Having the hardware type in Linux equal to the bfd
1588 printable name is deliberate: if you make config.guess
1589 work on your Linux-type system the usual way, it
1590 probably will; either the bfd printable_name or the
1591 ambiguous arch_name. */
1592 strcpy (sim_utsname
[4], STATE_ARCHITECTURE (sd
)->printable_name
);
1594 if ((s
.write_mem
) (cb
, &s
, arg1
, (const char *) sim_utsname
,
1595 sizeof (sim_utsname
))
1596 != sizeof (sim_utsname
))
1597 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
1603 case TARGET_SYS_geteuid32
:
1604 /* We tell the truth with these. Maybe we shouldn't, but it
1605 should match the "stat" information. */
1606 retval
= geteuid ();
1609 case TARGET_SYS_getuid32
:
1613 case TARGET_SYS_getegid32
:
1614 retval
= getegid ();
1617 case TARGET_SYS_getgid32
:
1621 case TARGET_SYS_brk
:
1622 /* Most often, we just return the argument, like the Linux
1627 retval
= current_cpu
->endbrk
;
1628 else if (arg1
<= current_cpu
->endmem
)
1629 current_cpu
->endbrk
= arg1
;
1632 USI new_end
= (arg1
+ 8191) & ~8191;
1634 /* If the simulator wants to brk more than a certain very
1635 large amount, something is wrong. FIXME: Return an error
1636 or abort? Have command-line selectable? */
1637 if (new_end
- current_cpu
->endmem
> SIM_MAX_ALLOC_CHUNK
)
1639 current_cpu
->endbrk
= current_cpu
->endmem
;
1640 retval
= current_cpu
->endmem
;
1644 sim_core_attach (sd
, NULL
, 0, access_read_write_exec
, 0,
1645 current_cpu
->endmem
,
1646 new_end
- current_cpu
->endmem
,
1648 current_cpu
->endbrk
= arg1
;
1649 current_cpu
->endmem
= new_end
;
1653 case TARGET_SYS_getpid
:
1654 /* Correct until CLONE_THREAD is implemented. */
1655 retval
= current_cpu
->thread_data
== NULL
1657 : TARGET_PID
+ current_cpu
->thread_data
[threadno
].threadid
;
1660 case TARGET_SYS_getppid
:
1661 /* Correct until CLONE_THREAD is implemented. */
1662 retval
= current_cpu
->thread_data
== NULL
1665 + current_cpu
->thread_data
[threadno
].parent_threadid
);
1668 case TARGET_SYS_mmap2
:
1677 /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1678 still masked away this bit, so let's just ignore
1680 flags
&= ~TARGET_MAP_DENYWRITE
;
1682 /* If the simulator wants to mmap more than the very large
1683 limit, something is wrong. FIXME: Return an error or
1684 abort? Have command-line selectable? */
1685 if (len
> SIM_MAX_ALLOC_CHUNK
)
1687 retval
= -cb_host_to_target_errno (cb
, ENOMEM
);
1691 if ((prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
)
1693 != (TARGET_PROT_READ
1695 | TARGET_PROT_EXEC
))
1696 && (prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
))
1697 && prot
!= TARGET_PROT_READ
)
1698 || (flags
!= (TARGET_MAP_ANONYMOUS
| TARGET_MAP_PRIVATE
)
1699 && flags
!= TARGET_MAP_PRIVATE
1700 && flags
!= (TARGET_MAP_ANONYMOUS
1701 | TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1702 && flags
!= (TARGET_MAP_PRIVATE
| TARGET_MAP_FIXED
)
1703 && flags
!= TARGET_MAP_SHARED
)
1705 && prot
!= TARGET_PROT_READ
1706 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1707 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1708 || (fd
== (USI
) -1 && pgoff
!= 0)
1709 || (fd
!= (USI
) -1 && (flags
& TARGET_MAP_ANONYMOUS
)))
1712 = cris_unknown_syscall (current_cpu
, pc
,
1713 "Unimplemented mmap2 call "
1714 "(0x%lx, 0x%lx, 0x%lx, "
1715 "0x%lx, 0x%lx, 0x%lx)\n",
1716 (unsigned long) arg1
,
1717 (unsigned long) arg2
,
1718 (unsigned long) arg3
,
1719 (unsigned long) arg4
,
1720 (unsigned long) arg5
,
1721 (unsigned long) arg6
);
1724 else if (fd
!= (USI
) -1)
1731 /* A non-aligned argument is allowed for files. */
1732 USI newlen
= (len
+ 8191) & ~8191;
1734 /* We only support read, read|exec, and read|write,
1735 which we should already have checked. Check again
1737 if (prot
!= TARGET_PROT_READ
1738 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_EXEC
)
1739 && prot
!= (TARGET_PROT_READ
| TARGET_PROT_WRITE
))
1742 if (flags
& TARGET_MAP_FIXED
)
1743 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1745 else if (is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1750 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1751 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1755 if (newaddr
>= (USI
) -8191)
1758 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1762 /* We were asked for MAP_FIXED, but couldn't. */
1763 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1766 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1768 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1772 /* Find the current position in the file. */
1773 s
.func
= TARGET_SYS_lseek
;
1777 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1784 /* Move to the correct offset in the file. */
1785 s
.func
= TARGET_SYS_lseek
;
1787 s
.arg2
= pgoff
*8192;
1789 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1795 /* Use the standard read callback to read in "len"
1797 s
.func
= TARGET_SYS_read
;
1801 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1804 /* If the result is a page or more lesser than what
1805 was requested, something went wrong. */
1806 if (len
>= 8192 && (USI
) s
.result
<= len
- 8192)
1809 /* After reading, we need to go back to the previous
1810 position in the file. */
1811 s
.func
= TARGET_SYS_lseek
;
1815 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1817 if (pos
!= (USI
) s
.result
)
1824 USI newlen
= (len
+ 8191) & ~8191;
1827 if (flags
& TARGET_MAP_FIXED
)
1828 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1830 else if (is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
1834 newaddr
= create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
1835 addr
!= 0 || (flags
& TARGET_MAP_FIXED
)
1839 if (newaddr
>= (USI
) -8191)
1840 retval
= -cb_host_to_target_errno (cb
, -(SI
) newaddr
);
1844 if ((flags
& TARGET_MAP_FIXED
) && newaddr
!= addr
)
1847 unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
1849 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1856 case TARGET_SYS_mprotect
:
1858 /* We only cover the case of linuxthreads mprotecting out
1859 its stack guard page and of dynamic loading mprotecting
1860 away the data (for some reason the whole library, then
1861 mprotects away the data part and mmap-FIX:es it again. */
1866 if (prot
!= TARGET_PROT_NONE
1867 || !is_mapped_only (sd
, ¤t_cpu
->highest_mmapped_page
,
1868 addr
, (len
+ 8191) & ~8191))
1871 = cris_unknown_syscall (current_cpu
, pc
,
1872 "Unimplemented mprotect call "
1873 "(0x%lx, 0x%lx, 0x%lx)\n",
1874 (unsigned long) arg1
,
1875 (unsigned long) arg2
,
1876 (unsigned long) arg3
);
1880 /* Just ignore this. We could make this equal to munmap,
1881 but then we'd have to make sure no anon mmaps gets this
1882 address before a subsequent MAP_FIXED mmap intended to
1888 case TARGET_SYS_ioctl
:
1890 /* We support only a very limited functionality: checking
1891 stdout with TCGETS to perform the isatty function. The
1892 TCGETS ioctl isn't actually performed or the result used by
1893 an isatty () caller in a "hello, world" program; only the
1894 return value is then used. Maybe we shouldn't care about
1895 the environment of the simulator regarding isatty, but
1896 that's been working before, in the xsim simulator. */
1897 if (arg2
== TARGET_TCGETS
&& arg1
== 1)
1898 retval
= isatty (1) ? 0 : cb_host_to_target_errno (cb
, EINVAL
);
1900 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
1904 case TARGET_SYS_munmap
:
1909 = unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
, addr
,
1911 retval
= result
!= 0 ? -cb_host_to_target_errno (cb
, result
) : 0;
1915 case TARGET_SYS_wait4
:
1923 /* FIXME: We're not properly implementing __WCLONE, and we
1924 don't really need the special casing so we might as well
1925 make this general. */
1926 if ((!(pid
== (USI
) -1
1927 && options
== (TARGET___WCLONE
| TARGET_WNOHANG
)
1930 && (options
== TARGET___WCLONE
1931 || options
== TARGET___WALL
)))
1933 || current_cpu
->thread_data
== NULL
)
1936 = cris_unknown_syscall (current_cpu
, pc
,
1937 "Unimplemented wait4 call "
1938 "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1939 (unsigned long) arg1
,
1940 (unsigned long) arg2
,
1941 (unsigned long) arg3
,
1942 (unsigned long) arg4
);
1946 if (pid
== (USI
) -1)
1947 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1949 if (current_cpu
->thread_data
[threadno
].threadid
1950 == current_cpu
->thread_data
[i
].parent_threadid
1951 && current_cpu
->thread_data
[i
].threadid
!= 0
1952 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1954 /* A zombied child. Get the exit value and clear the
1955 zombied entry so it will be reused. */
1956 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, saddr
,
1958 ->thread_data
[i
].exitval
);
1960 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1961 memset (¤t_cpu
->thread_data
[i
], 0,
1962 sizeof (current_cpu
->thread_data
[i
]));
1968 /* We're waiting for a specific PID. If we don't find
1969 it zombied on this run, rerun the syscall. */
1970 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
1971 if (pid
== current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
1972 && current_cpu
->thread_data
[i
].cpu_context
== NULL
)
1975 /* Get the exit value if the caller wants it. */
1976 sim_core_write_unaligned_4 (current_cpu
, pc
, 0,
1983 = current_cpu
->thread_data
[i
].threadid
+ TARGET_PID
;
1984 memset (¤t_cpu
->thread_data
[i
], 0,
1985 sizeof (current_cpu
->thread_data
[i
]));
1990 sim_pc_set (current_cpu
, pc
);
1993 retval
= -cb_host_to_target_errno (cb
, ECHILD
);
1998 case TARGET_SYS_rt_sigaction
:
2006 __sighandler_t sa_handler;
2007 unsigned long sa_flags;
2008 void (*sa_restorer)(void);
2014 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, old_sa
+ 0,
2015 current_cpu
->sighandler
[signum
]);
2016 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 4, 0);
2017 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 8, 0);
2019 /* We'll assume _NSIG_WORDS is 2 for the kernel. */
2020 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 12, 0);
2021 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg3
+ 16, 0);
2025 USI target_sa_handler
2026 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
);
2028 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 4);
2029 USI target_sa_restorer
2030 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 8);
2031 USI target_sa_mask_low
2032 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 12);
2033 USI target_sa_mask_high
2034 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, new_sa
+ 16);
2036 /* We won't interrupt a syscall so we won't restart it,
2037 but a signal(2) call ends up syscalling rt_sigaction
2038 with this flag, so we have to handle it. The
2039 sa_restorer field contains garbage when not
2040 TARGET_SA_RESTORER, so don't look at it. For the
2041 time being, we don't nest sighandlers, so we
2042 ignore the sa_mask, which simplifies things. */
2043 if ((target_sa_flags
!= 0
2044 && target_sa_flags
!= TARGET_SA_RESTART
2045 && target_sa_flags
!= (TARGET_SA_RESTART
|TARGET_SA_SIGINFO
))
2046 || target_sa_handler
== 0)
2049 = cris_unknown_syscall (current_cpu
, pc
,
2050 "Unimplemented rt_sigaction "
2053 "[0x%x, 0x%x, 0x%x, "
2054 "{0x%x, 0x%x}], 0x%lx)\n",
2055 (unsigned long) arg1
,
2056 (unsigned long) arg2
,
2061 target_sa_mask_high
,
2062 (unsigned long) arg3
);
2066 current_cpu
->sighandler
[signum
] = target_sa_handler
;
2068 /* Because we may have unblocked signals, one may now be
2069 pending, if there are threads, that is. */
2070 if (current_cpu
->thread_data
)
2071 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2077 case TARGET_SYS_mremap
:
2083 USI new_addr
= arg5
;
2086 if (new_len
== old_len
)
2087 /* The program and/or library is possibly confused but
2088 this is a valid call. Happens with ipps-1.40 on file
2091 else if (new_len
< old_len
)
2093 /* Shrinking is easy. */
2094 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2095 addr
+ new_len
, old_len
- new_len
) != 0)
2096 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2100 else if (! is_mapped (sd
, ¤t_cpu
->highest_mmapped_page
,
2101 addr
+ old_len
, new_len
- old_len
))
2103 /* If the extension isn't mapped, we can just add it. */
2105 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2106 addr
+ old_len
, new_len
- old_len
);
2108 if (mapped_addr
> (USI
) -8192)
2109 retval
= -cb_host_to_target_errno (cb
, -(SI
) mapped_addr
);
2113 else if (flags
& TARGET_MREMAP_MAYMOVE
)
2115 /* Create a whole new map and copy the contents
2116 block-by-block there. We ignore the new_addr argument
2119 USI prev_addr
= addr
;
2120 USI prev_len
= old_len
;
2123 = create_map (sd
, ¤t_cpu
->highest_mmapped_page
,
2126 if (mapped_addr
> (USI
) -8192)
2128 retval
= -cb_host_to_target_errno (cb
, -(SI
) new_addr
);
2132 retval
= mapped_addr
;
2135 old_len
-= 8192, mapped_addr
+= 8192, addr
+= 8192)
2137 if (sim_core_read_buffer (sd
, current_cpu
, read_map
, buf
,
2139 || sim_core_write_buffer (sd
, current_cpu
, 0, buf
,
2140 mapped_addr
, 8192) != 8192)
2144 if (unmap_pages (sd
, ¤t_cpu
->highest_mmapped_page
,
2145 prev_addr
, prev_len
) != 0)
2149 retval
= -cb_host_to_target_errno (cb
, -ENOMEM
);
2153 case TARGET_SYS_poll
:
2155 int npollfds
= arg2
;
2171 /* Check that this is the expected poll call from
2172 linuxthreads/manager.c; we don't support anything else.
2173 Remember, fd == 0 isn't supported. */
2175 || ((fd
= sim_core_read_unaligned_4 (current_cpu
, pc
,
2177 || ((events
= sim_core_read_unaligned_2 (current_cpu
, pc
,
2180 || ((cb
->to_fstat
) (cb
, fd
, &buf
) != 0
2181 || (buf
.st_mode
& S_IFIFO
) == 0)
2182 || current_cpu
->thread_data
== NULL
)
2185 = cris_unknown_syscall (current_cpu
, pc
,
2186 "Unimplemented poll syscall "
2187 "(0x%lx: [0x%x, 0x%x, x], "
2189 (unsigned long) arg1
, fd
, events
,
2190 (unsigned long) arg2
,
2191 (unsigned long) arg3
);
2197 /* Iterate over threads; find a marker that a writer is
2198 sleeping, waiting for a reader. */
2199 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
2200 if (current_cpu
->thread_data
[i
].cpu_context
!= NULL
2201 && current_cpu
->thread_data
[i
].pipe_read_fd
== fd
)
2203 revents
= TARGET_POLLIN
;
2208 /* Timeout decreases with whatever time passed between the
2209 last syscall and this. That's not exactly right for the
2210 first call, but it's close enough that it isn't
2211 worthwhile to complicate matters by making that a special
2214 -= (TARGET_TIME_MS (current_cpu
)
2215 - (current_cpu
->thread_data
[threadno
].last_execution
));
2217 /* Arrange to repeat this syscall until timeout or event,
2218 decreasing timeout at each iteration. */
2219 if (timeout
> 0 && revents
== 0)
2221 bfd_byte timeout_buf
[4];
2223 bfd_putl32 (timeout
, timeout_buf
);
2224 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
2225 H_GR_R12
, timeout_buf
, 4);
2226 sim_pc_set (current_cpu
, pc
);
2231 sim_core_write_unaligned_2 (current_cpu
, pc
, 0, ufds
+ 4 + 2,
2236 case TARGET_SYS_time
:
2238 retval
= (int) (*cb
->time
) (cb
, 0L);
2240 /* At time of this writing, CB_SYSCALL_time doesn't do the
2241 part of setting *arg1 to the return value. */
2243 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, retval
);
2247 case TARGET_SYS_gettimeofday
:
2250 USI ts
= TARGET_TIME (current_cpu
);
2251 USI tms
= TARGET_TIME_MS (current_cpu
);
2253 /* First dword is seconds since TARGET_EPOCH. */
2254 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
, ts
);
2256 /* Second dword is microseconds. */
2257 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4,
2258 (tms
% 1000) * 1000);
2262 /* Time-zone info is always cleared. */
2263 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, 0);
2264 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, 0);
2269 case TARGET_SYS_llseek
:
2271 /* If it fits, tweak parameters to fit the "generic" 32-bit
2272 lseek and use that. */
2280 if (!((offs_hi
== 0 && offs_lo
>= 0)
2281 || (offs_hi
== -1 && offs_lo
< 0)))
2284 = cris_unknown_syscall (current_cpu
, pc
,
2285 "Unimplemented llseek offset,"
2286 " fd %d: 0x%x:0x%x\n",
2287 fd
, (unsigned) arg2
,
2292 s
.func
= TARGET_SYS_lseek
;
2295 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2297 sim_io_eprintf (sd
, "Break 13: invalid %d? Returned %ld\n", callnum
,
2299 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
, SIM_SIGILL
);
2302 retval
= -s
.errcode
;
2305 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
,
2307 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, resultp
+ 4,
2308 s
.result
< 0 ? -1 : 0);
2313 /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2316 void *iov_base; Starting address
2317 size_t iov_len; Number of bytes to transfer
2319 case TARGET_SYS_writev
:
2327 /* We'll ignore strict error-handling and just do multiple write calls. */
2328 for (i
= 0; i
< iovcnt
; i
++)
2332 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2335 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2338 s
.func
= TARGET_SYS_write
;
2343 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2345 sysret
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2347 if (sysret
!= iov_len
)
2362 /* This one does have a generic callback function, but at the time
2363 of this writing, cb_syscall does not have code for it, and we
2364 need target-specific code for the threads implementation
2366 case TARGET_SYS_kill
:
2373 /* At kill(2), glibc sets signal masks such that the thread
2374 machinery is initialized. Still, there is and was only
2376 if (current_cpu
->max_threadid
== 0)
2378 if (pid
!= TARGET_PID
)
2380 retval
= -cb_host_to_target_errno (cb
, EPERM
);
2384 /* FIXME: Signal infrastructure (target-to-sim mapping). */
2385 if (sig
== TARGET_SIGABRT
)
2386 /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2387 the end-point for failing GCC test-cases. */
2388 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2392 sim_io_eprintf (sd
, "Unimplemented signal: %d\n", sig
);
2393 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2397 /* This will not be reached. */
2401 retval
= deliver_signal (current_cpu
, sig
, pid
);
2405 case TARGET_SYS_rt_sigprocmask
:
2412 if (how
!= TARGET_SIG_BLOCK
2413 && how
!= TARGET_SIG_SETMASK
2414 && how
!= TARGET_SIG_UNBLOCK
)
2417 = cris_unknown_syscall (current_cpu
, pc
,
2418 "Unimplemented rt_sigprocmask "
2419 "syscall (0x%x, 0x%x, 0x%x)\n",
2427 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2430 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2433 /* The sigmask is kept in the per-thread data, so we may
2434 need to create the first one. */
2435 if (current_cpu
->thread_data
== NULL
)
2436 make_first_thread (current_cpu
);
2438 if (how
== TARGET_SIG_SETMASK
)
2439 for (i
= 0; i
< 64; i
++)
2440 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
= 0;
2442 for (i
= 0; i
< 32; i
++)
2443 if ((set_low
& (1 << i
)))
2444 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2445 = (how
!= TARGET_SIG_UNBLOCK
);
2447 for (i
= 0; i
< 31; i
++)
2448 if ((set_high
& (1 << i
)))
2449 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2450 = (how
!= TARGET_SIG_UNBLOCK
);
2452 /* The mask changed, so a signal may be unblocked for
2454 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2462 for (i
= 0; i
< 32; i
++)
2463 if (current_cpu
->thread_data
[threadno
]
2464 .sigdata
[i
+ 1].blocked
)
2466 for (i
= 0; i
< 31; i
++)
2467 if (current_cpu
->thread_data
[threadno
]
2468 .sigdata
[i
+ 33].blocked
)
2471 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 0, set_low
);
2472 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldsetp
+ 4, set_high
);
2479 case TARGET_SYS_sigreturn
:
2483 int was_sigsuspended
;
2485 if (current_cpu
->thread_data
== NULL
2486 /* The CPU context is saved with the simulator data, not
2487 on the stack as in the real world. */
2488 || (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
2492 = cris_unknown_syscall (current_cpu
, pc
,
2493 "Invalid sigreturn syscall: "
2494 "no signal handler active "
2495 "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2497 (unsigned long) arg1
,
2498 (unsigned long) arg2
,
2499 (unsigned long) arg3
,
2500 (unsigned long) arg4
,
2501 (unsigned long) arg5
,
2502 (unsigned long) arg6
);
2507 = current_cpu
->thread_data
[threadno
].sigsuspended
;
2509 /* Restore the sigmask, either from the stack copy made when
2510 the sighandler was called, or from the saved state
2511 specifically for sigsuspend(2). */
2512 if (was_sigsuspended
)
2514 current_cpu
->thread_data
[threadno
].sigsuspended
= 0;
2515 for (i
= 0; i
< 64; i
++)
2516 current_cpu
->thread_data
[threadno
].sigdata
[i
].blocked
2517 = current_cpu
->thread_data
[threadno
]
2518 .sigdata
[i
].blocked_suspendsave
;
2526 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
2527 H_GR_SP
, regbuf
, 4);
2528 sp
= bfd_getl32 (regbuf
);
2530 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
);
2532 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, sp
+ 4);
2534 for (i
= 0; i
< 32; i
++)
2535 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 1].blocked
2536 = (set_low
& (1 << i
)) != 0;
2537 for (i
= 0; i
< 31; i
++)
2538 current_cpu
->thread_data
[threadno
].sigdata
[i
+ 33].blocked
2539 = (set_high
& (1 << i
)) != 0;
2542 /* The mask changed, so a signal may be unblocked for
2544 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2546 memcpy (¤t_cpu
->cpu_data_placeholder
,
2547 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
,
2548 current_cpu
->thread_cpu_data_size
);
2549 free (current_cpu
->thread_data
[threadno
].cpu_context_atsignal
);
2550 current_cpu
->thread_data
[threadno
].cpu_context_atsignal
= NULL
;
2552 /* The return value must come from the saved R10. */
2553 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, regbuf
, 4);
2554 retval
= bfd_getl32 (regbuf
);
2556 /* We must also break the "sigsuspension loop". */
2557 if (was_sigsuspended
)
2558 sim_pc_set (current_cpu
, sim_pc_get (current_cpu
) + 2);
2562 case TARGET_SYS_rt_sigsuspend
:
2570 = cris_unknown_syscall (current_cpu
, pc
,
2571 "Unimplemented rt_sigsuspend syscall"
2572 " arguments (0x%lx, 0x%lx)\n",
2573 (unsigned long) arg1
,
2574 (unsigned long) arg2
);
2578 /* Don't change the signal mask if we're already in
2579 sigsuspend state (i.e. this syscall is a rerun). */
2580 else if (!current_cpu
->thread_data
[threadno
].sigsuspended
)
2583 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2586 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2590 /* Save the current sigmask and insert the user-supplied
2592 for (i
= 0; i
< 32; i
++)
2594 current_cpu
->thread_data
[threadno
]
2595 .sigdata
[i
+ 1].blocked_suspendsave
2596 = current_cpu
->thread_data
[threadno
]
2597 .sigdata
[i
+ 1].blocked
;
2599 current_cpu
->thread_data
[threadno
]
2600 .sigdata
[i
+ 1].blocked
= (set_low
& (1 << i
)) != 0;
2602 for (i
= 0; i
< 31; i
++)
2604 current_cpu
->thread_data
[threadno
]
2605 .sigdata
[i
+ 33].blocked_suspendsave
2606 = current_cpu
->thread_data
[threadno
]
2607 .sigdata
[i
+ 33].blocked
;
2608 current_cpu
->thread_data
[threadno
]
2609 .sigdata
[i
+ 33].blocked
= (set_high
& (1 << i
)) != 0;
2612 current_cpu
->thread_data
[threadno
].sigsuspended
= 1;
2614 /* The mask changed, so a signal may be unblocked for
2616 current_cpu
->thread_data
[threadno
].sigpending
= 1;
2619 /* Because we don't use arg1 (newsetp) when this syscall is
2620 rerun, it doesn't matter that we overwrite it with the
2621 (constant) return value. */
2622 retval
= -cb_host_to_target_errno (cb
, EINTR
);
2623 sim_pc_set (current_cpu
, pc
);
2627 /* Add case labels here for other syscalls using the 32-bit
2628 "struct stat", provided they have a corresponding simulator
2629 function of course. */
2630 case TARGET_SYS_stat
:
2631 case TARGET_SYS_fstat
:
2633 /* As long as the infrastructure doesn't cache anything
2634 related to the stat mapping, this trick gets us a dual
2635 "struct stat"-type mapping in the least error-prone way. */
2636 const char *saved_map
= cb
->stat_map
;
2637 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
2639 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_stat32_map
;
2640 cb
->stat_map
= stat32_map
;
2642 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
2645 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
2648 retval
= s
.result
== -1 ? -s
.errcode
: s
.result
;
2650 cb
->stat_map
= saved_map
;
2651 cb
->syscall_map
= saved_syscall_map
;
2655 case TARGET_SYS_getcwd
:
2660 char *cwd
= xmalloc (SIM_PATHMAX
);
2661 if (cwd
!= getcwd (cwd
, SIM_PATHMAX
))
2664 /* FIXME: When and if we support chdir, we need something
2665 a bit more elaborate. */
2666 if (simulator_sysroot
[0] != '\0')
2669 retval
= -cb_host_to_target_errno (cb
, ERANGE
);
2670 if (strlen (cwd
) + 1 <= size
)
2672 retval
= strlen (cwd
) + 1;
2673 if (sim_core_write_buffer (sd
, current_cpu
, 0, cwd
,
2675 != (unsigned int) retval
)
2676 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2682 case TARGET_SYS_access
:
2686 char *pbuf
= xmalloc (SIM_PATHMAX
);
2691 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2693 strcpy (pbuf
, simulator_sysroot
);
2694 o
+= strlen (simulator_sysroot
);
2697 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2700 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2701 if (pbuf
[i
+ o
] == 0)
2705 if (i
+ o
== SIM_PATHMAX
)
2707 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2711 /* Assert that we don't get calls for files for which we
2712 don't have support. */
2713 if (strncmp (pbuf
+ strlen (simulator_sysroot
),
2716 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2723 if (access (pbuf
, hmode
) != 0)
2724 retval
= -cb_host_to_target_errno (cb
, errno
);
2732 case TARGET_SYS_readlink
:
2737 char *pbuf
= xmalloc (SIM_PATHMAX
);
2738 char *lbuf
= xmalloc (SIM_PATHMAX
);
2739 char *lbuf_alloc
= lbuf
;
2744 if (sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
) == '/')
2746 strcpy (pbuf
, simulator_sysroot
);
2747 o
+= strlen (simulator_sysroot
);
2750 for (i
= 0; i
+ o
< SIM_PATHMAX
; i
++)
2753 = sim_core_read_unaligned_1 (current_cpu
, pc
, 0, path
+ i
);
2754 if (pbuf
[i
+ o
] == 0)
2758 if (i
+ o
== SIM_PATHMAX
)
2760 retval
= -cb_host_to_target_errno (cb
, ENAMETOOLONG
);
2764 /* Intervene calls for certain files expected in the target
2765 proc file system. */
2766 if (strcmp (pbuf
+ strlen (simulator_sysroot
),
2767 "/proc/" XSTRING (TARGET_PID
) "/exe") == 0)
2770 = (STATE_PROG_ARGV (sd
) != NULL
2771 ? *STATE_PROG_ARGV (sd
) : NULL
);
2773 if (argv0
== NULL
|| *argv0
== '.')
2776 = cris_unknown_syscall (current_cpu
, pc
,
2777 "Unimplemented readlink syscall "
2778 "(0x%lx: [\"%s\"], 0x%lx)\n",
2779 (unsigned long) arg1
, pbuf
,
2780 (unsigned long) arg2
);
2783 else if (*argv0
== '/')
2785 if (strncmp (simulator_sysroot
, argv0
,
2786 strlen (simulator_sysroot
)) == 0)
2787 argv0
+= strlen (simulator_sysroot
);
2789 strcpy (lbuf
, argv0
);
2790 nchars
= strlen (argv0
) + 1;
2794 if (getcwd (lbuf
, SIM_PATHMAX
) != NULL
2795 && strlen (lbuf
) + 2 + strlen (argv0
) < SIM_PATHMAX
)
2797 if (strncmp (simulator_sysroot
, lbuf
,
2798 strlen (simulator_sysroot
)) == 0)
2799 lbuf
+= strlen (simulator_sysroot
);
2802 strcat (lbuf
, argv0
);
2803 nchars
= strlen (lbuf
) + 1;
2810 nchars
= readlink (pbuf
, lbuf
, SIM_PATHMAX
);
2812 /* We trust that the readlink result returns a *relative*
2813 link, or one already adjusted for the file-path-prefix.
2814 (We can't generally tell the difference, so we go with
2815 the easiest decision; no adjustment.) */
2819 retval
= -cb_host_to_target_errno (cb
, errno
);
2823 if (bufsiz
< nchars
)
2826 if (sim_core_write_buffer (sd
, current_cpu
, write_map
, lbuf
,
2827 buf
, nchars
) != (unsigned int) nchars
)
2828 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
2837 case TARGET_SYS_sched_getscheduler
:
2841 /* FIXME: Search (other) existing threads. */
2842 if (pid
!= 0 && pid
!= TARGET_PID
)
2843 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2845 retval
= TARGET_SCHED_OTHER
;
2849 case TARGET_SYS_sched_getparam
:
2855 struct sched_param {
2859 if (pid
!= 0 && pid
!= TARGET_PID
)
2860 retval
= -cb_host_to_target_errno (cb
, ESRCH
);
2863 /* FIXME: Save scheduler setting before threads are
2865 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, paramp
,
2866 current_cpu
->thread_data
!= NULL
2868 ->thread_data
[threadno
]
2876 case TARGET_SYS_sched_setparam
:
2881 if ((pid
!= 0 && pid
!= TARGET_PID
)
2882 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2884 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2890 case TARGET_SYS_sched_setscheduler
:
2896 if ((pid
!= 0 && pid
!= TARGET_PID
)
2897 || policy
!= TARGET_SCHED_OTHER
2898 || sim_core_read_unaligned_4 (current_cpu
, pc
, 0,
2900 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2902 /* FIXME: Save scheduler setting to be read in later
2903 sched_getparam calls. */
2908 case TARGET_SYS_sched_yield
:
2909 /* We reschedule to the next thread after a syscall anyway, so
2910 we don't have to do anything here than to set the return
2915 case TARGET_SYS_sched_get_priority_min
:
2916 case TARGET_SYS_sched_get_priority_max
:
2918 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2923 case TARGET_SYS_ugetrlimit
:
2925 unsigned int curlim
, maxlim
;
2926 if (arg1
!= TARGET_RLIMIT_STACK
&& arg1
!= TARGET_RLIMIT_NOFILE
)
2928 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2934 unsigned long rlim_cur;
2935 unsigned long rlim_max;
2937 if (arg1
== TARGET_RLIMIT_NOFILE
)
2939 /* Sadly a very low limit. Better not lie, though. */
2940 maxlim
= curlim
= MAX_CALLBACK_FDS
;
2942 else /* arg1 == TARGET_RLIMIT_STACK */
2944 maxlim
= 0xffffffff;
2947 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
, curlim
);
2948 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, arg2
+ 4, maxlim
);
2953 case TARGET_SYS_setrlimit
:
2954 if (arg1
!= TARGET_RLIMIT_STACK
)
2956 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
2959 /* FIXME: Save values for future ugetrlimit calls. */
2963 /* Provide a very limited subset of the sysctl functions, and
2964 abort for the rest. */
2965 case TARGET_SYS__sysctl
:
2968 struct __sysctl_args {
2975 unsigned long __unused[4];
2977 SI name
= sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
);
2978 SI name0
= name
== 0
2979 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
);
2980 SI name1
= name
== 0
2981 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, name
+ 4);
2983 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 4);
2985 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 8);
2987 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 12);
2988 SI oldlen
= oldlenp
== 0
2989 ? 0 : sim_core_read_unaligned_4 (current_cpu
, pc
, 0, oldlenp
);
2991 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 16);
2993 = sim_core_read_unaligned_4 (current_cpu
, pc
, 0, arg1
+ 20);
2995 if (name0
== TARGET_CTL_KERN
&& name1
== TARGET_CTL_KERN_VERSION
)
2997 SI to_write
= oldlen
< (SI
) sizeof (TARGET_UTSNAME
)
2998 ? oldlen
: (SI
) sizeof (TARGET_UTSNAME
);
3000 sim_core_write_unaligned_4 (current_cpu
, pc
, 0, oldlenp
,
3001 sizeof (TARGET_UTSNAME
));
3003 if (sim_core_write_buffer (sd
, current_cpu
, write_map
,
3004 TARGET_UTSNAME
, oldval
,
3006 != (unsigned int) to_write
)
3007 retval
= -cb_host_to_target_errno (cb
, EFAULT
);
3014 = cris_unknown_syscall (current_cpu
, pc
,
3015 "Unimplemented _sysctl syscall "
3016 "(0x%lx: [0x%lx, 0x%lx],"
3017 " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
3018 (unsigned long) name
,
3019 (unsigned long) name0
,
3020 (unsigned long) name1
,
3021 (unsigned long) nlen
,
3022 (unsigned long) oldval
,
3023 (unsigned long) oldlenp
,
3024 (unsigned long) newval
,
3025 (unsigned long) newlen
);
3029 case TARGET_SYS_exit
:
3031 /* Here for all but the last thread. */
3034 = current_cpu
->thread_data
[threadno
].threadid
+ TARGET_PID
;
3036 = (current_cpu
->thread_data
[threadno
].parent_threadid
3038 int exitsig
= current_cpu
->thread_data
[threadno
].exitsig
;
3040 /* Any children are now all orphans. */
3041 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3042 if (current_cpu
->thread_data
[i
].parent_threadid
3043 == current_cpu
->thread_data
[threadno
].threadid
)
3044 /* Make getppid(2) return 1 for them, poor little ones. */
3045 current_cpu
->thread_data
[i
].parent_threadid
= -TARGET_PID
+ 1;
3047 /* Free the cpu context data. When the parent has received
3048 the exit status, we'll clear the entry too. */
3049 free (current_cpu
->thread_data
[threadno
].cpu_context
);
3050 current_cpu
->thread_data
[threadno
].cpu_context
= NULL
;
3051 current_cpu
->m1threads
--;
3054 sim_io_eprintf (sd
, "Thread %d exited with status %d\n",
3056 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_stopped
,
3060 /* Still, we may want to support non-zero exit values. */
3061 current_cpu
->thread_data
[threadno
].exitval
= arg1
<< 8;
3064 deliver_signal (current_cpu
, exitsig
, ppid
);
3068 case TARGET_SYS_clone
:
3070 int nthreads
= current_cpu
->m1threads
+ 1;
3071 void *thread_cpu_data
;
3072 bfd_byte old_sp_buf
[4];
3074 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3077 /* That's right, the syscall clone arguments are reversed
3078 compared to sys_clone notes in clone(2) and compared to
3079 other Linux ports (i.e. it's the same order as in the
3080 clone(2) libcall). */
3084 if (nthreads
== SIM_TARGET_MAX_THREADS
)
3086 retval
= -cb_host_to_target_errno (cb
, EAGAIN
);
3090 /* FIXME: Implement the low byte. */
3091 if ((flags
& ~TARGET_CSIGNAL
) !=
3094 | TARGET_CLONE_FILES
3095 | TARGET_CLONE_SIGHAND
)
3099 = cris_unknown_syscall (current_cpu
, pc
,
3100 "Unimplemented clone syscall "
3102 (unsigned long) arg1
,
3103 (unsigned long) arg2
);
3107 if (current_cpu
->thread_data
== NULL
)
3108 make_first_thread (current_cpu
);
3110 /* The created thread will get the new SP and a cleared R10.
3111 Since it's created out of a copy of the old thread and we
3112 don't have a set-register-function that just take the
3113 cpu_data as a parameter, we set the childs values first,
3114 and write back or overwrite them in the parent after the
3116 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
,
3117 H_GR_SP
, old_sp_buf
, 4);
3118 bfd_putl32 (newsp
, sp_buf
);
3119 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3120 H_GR_SP
, sp_buf
, 4);
3121 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3122 H_GR_R10
, (bfd_byte
*) zeros
, 4);
3125 ->make_thread_cpu_data
) (current_cpu
,
3126 ¤t_cpu
->cpu_data_placeholder
);
3127 (*CPU_REG_STORE (current_cpu
)) (current_cpu
,
3128 H_GR_SP
, old_sp_buf
, 4);
3130 retval
= ++current_cpu
->max_threadid
+ TARGET_PID
;
3132 /* Find an unused slot. After a few threads have been created
3133 and exited, the array is expected to be a bit fragmented.
3134 We don't reuse the first entry, though, that of the
3136 for (i
= 1; i
< SIM_TARGET_MAX_THREADS
; i
++)
3137 if (current_cpu
->thread_data
[i
].cpu_context
== NULL
3138 /* Don't reuse a zombied entry. */
3139 && current_cpu
->thread_data
[i
].threadid
== 0)
3142 memcpy (¤t_cpu
->thread_data
[i
],
3143 ¤t_cpu
->thread_data
[threadno
],
3144 sizeof (current_cpu
->thread_data
[i
]));
3145 current_cpu
->thread_data
[i
].cpu_context
= thread_cpu_data
;
3146 current_cpu
->thread_data
[i
].cpu_context_atsignal
= NULL
;
3147 current_cpu
->thread_data
[i
].threadid
= current_cpu
->max_threadid
;
3148 current_cpu
->thread_data
[i
].parent_threadid
3149 = current_cpu
->thread_data
[threadno
].threadid
;
3150 current_cpu
->thread_data
[i
].pipe_read_fd
= 0;
3151 current_cpu
->thread_data
[i
].pipe_write_fd
= 0;
3152 current_cpu
->thread_data
[i
].at_syscall
= 0;
3153 current_cpu
->thread_data
[i
].sigpending
= 0;
3154 current_cpu
->thread_data
[i
].sigsuspended
= 0;
3155 current_cpu
->thread_data
[i
].exitsig
= flags
& TARGET_CSIGNAL
;
3156 current_cpu
->m1threads
= nthreads
;
3160 /* Better watch these in case they do something necessary. */
3161 case TARGET_SYS_socketcall
:
3162 retval
= -cb_host_to_target_errno (cb
, ENOSYS
);
3165 case TARGET_SYS_set_thread_area
:
3166 /* Do the same error check as Linux. */
3169 retval
= -cb_host_to_target_errno (cb
, EINVAL
);
3172 (*current_cpu
->set_target_thread_data
) (current_cpu
, arg1
);
3176 unimplemented_syscall
:
3179 = cris_unknown_syscall (current_cpu
, pc
,
3180 "Unimplemented syscall: %d "
3181 "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3182 callnum
, arg1
, arg2
, arg3
, arg4
, arg5
,
3187 /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
3188 if (callnum
== TARGET_SYS_open
)
3190 current_cpu
->last_open_fd
= retval
;
3191 current_cpu
->last_open_flags
= arg2
;
3194 current_cpu
->last_syscall
= callnum
;
3196 /* A system call is a rescheduling point. For the time being, we don't
3197 reschedule anywhere else. */
3198 if (current_cpu
->m1threads
!= 0
3199 /* We need to schedule off from an exiting thread that is the
3201 || (current_cpu
->thread_data
!= NULL
3202 && current_cpu
->thread_data
[threadno
].cpu_context
== NULL
))
3204 bfd_byte retval_buf
[4];
3206 current_cpu
->thread_data
[threadno
].last_execution
3207 = TARGET_TIME_MS (current_cpu
);
3208 bfd_putl32 (retval
, retval_buf
);
3209 (*CPU_REG_STORE (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3211 current_cpu
->thread_data
[threadno
].at_syscall
= 1;
3212 reschedule (current_cpu
);
3214 (*CPU_REG_FETCH (current_cpu
)) (current_cpu
, H_GR_R10
, retval_buf
, 4);
3215 retval
= bfd_getl32 (retval_buf
);
3221 /* Callback from simulator write saying that the pipe at (reader, writer)
3222 is now non-empty (so the writer should wait until the pipe is empty, at
3223 least not write to this or any other pipe). Simplest is to just wait
3224 until the pipe is empty. */
3227 cris_pipe_nonempty (host_callback
*cb ATTRIBUTE_UNUSED
,
3228 int reader
, int writer
)
3230 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3231 const bfd_byte zeros
[4] = { 0, 0, 0, 0 };
3233 /* It's the current thread: we just have to re-run the current
3234 syscall instruction (presumably "break 13") and change the syscall
3235 to the special simulator-wait code. Oh, and set a marker that
3236 we're waiting, so we can disambiguate the special call from a
3239 This function may be called multiple times between cris_pipe_empty,
3240 but we must avoid e.g. decreasing PC every time. Check fd markers
3242 if (cpu
->thread_data
== NULL
)
3244 sim_io_eprintf (CPU_STATE (cpu
),
3245 "Terminating simulation due to writing pipe rd:wr %d:%d"
3246 " from one single thread\n", reader
, writer
);
3247 sim_engine_halt (CPU_STATE (cpu
), cpu
,
3248 NULL
, sim_pc_get (cpu
), sim_stopped
, SIM_SIGILL
);
3250 else if (cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
== 0)
3252 cpu
->thread_data
[cpu
->threadno
].pipe_write_fd
= writer
;
3253 cpu
->thread_data
[cpu
->threadno
].pipe_read_fd
= reader
;
3254 /* FIXME: We really shouldn't change registers other than R10 in
3255 syscalls (like R9), here or elsewhere. */
3256 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R9
, (bfd_byte
*) zeros
, 4);
3257 sim_pc_set (cpu
, sim_pc_get (cpu
) - 2);
3261 /* Callback from simulator close or read call saying that the pipe at
3262 (reader, writer) is now empty (so the writer can write again, perhaps
3263 leave a waiting state). If there are bytes remaining, they couldn't be
3264 consumed (perhaps due to the pipe closing). */
3267 cris_pipe_empty (host_callback
*cb
,
3272 SIM_CPU
*cpu
= current_cpu_for_cb_callback
;
3273 SIM_DESC sd
= CPU_STATE (current_cpu_for_cb_callback
);
3274 bfd_byte r10_buf
[4];
3276 = cb
->pipe_buffer
[writer
].size
- cb
->pipe_buffer
[reader
].size
;
3278 /* We need to find the thread that waits for this pipe. */
3279 for (i
= 0; i
< SIM_TARGET_MAX_THREADS
; i
++)
3280 if (cpu
->thread_data
[i
].cpu_context
3281 && cpu
->thread_data
[i
].pipe_write_fd
== writer
)
3285 /* Temporarily switch to this cpu context, so we can change the
3286 PC by ordinary calls. */
3288 memcpy (cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3289 &cpu
->cpu_data_placeholder
,
3290 cpu
->thread_cpu_data_size
);
3291 memcpy (&cpu
->cpu_data_placeholder
,
3292 cpu
->thread_data
[i
].cpu_context
,
3293 cpu
->thread_cpu_data_size
);
3295 /* The return value is supposed to contain the number of
3296 written bytes, which is the number of bytes requested and
3297 returned at the write call. You might think the right
3298 thing is to adjust the return-value to be only the
3299 *consumed* number of bytes, but it isn't. We're only
3300 called if the pipe buffer is fully consumed or it is being
3301 closed, possibly with remaining bytes. For the latter
3302 case, the writer is still supposed to see success for
3303 PIPE_BUF bytes (a constant which we happen to know and is
3304 unlikely to change). The return value may also be a
3305 negative number; an error value. This case is covered
3306 because "remaining" is always >= 0. */
3307 (*CPU_REG_FETCH (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3308 retval
= (int) bfd_getl_signed_32 (r10_buf
);
3309 if (retval
- remaining
> TARGET_PIPE_BUF
)
3311 bfd_putl32 (retval
- remaining
, r10_buf
);
3312 (*CPU_REG_STORE (cpu
)) (cpu
, H_GR_R10
, r10_buf
, 4);
3314 sim_pc_set (cpu
, sim_pc_get (cpu
) + 2);
3315 memcpy (cpu
->thread_data
[i
].cpu_context
,
3316 &cpu
->cpu_data_placeholder
,
3317 cpu
->thread_cpu_data_size
);
3318 memcpy (&cpu
->cpu_data_placeholder
,
3319 cpu
->thread_data
[cpu
->threadno
].cpu_context
,
3320 cpu
->thread_cpu_data_size
);
3321 cpu
->thread_data
[i
].pipe_read_fd
= 0;
3322 cpu
->thread_data
[i
].pipe_write_fd
= 0;
3329 /* We have a simulator-specific notion of time. See TARGET_TIME. */
3332 cris_time (host_callback
*cb ATTRIBUTE_UNUSED
, long *t
)
3334 long retval
= TARGET_TIME (current_cpu_for_cb_callback
);
3340 /* Set target-specific callback data. */
3343 cris_set_callbacks (host_callback
*cb
)
3345 /* Yeargh, have to cast away constness to avoid warnings. */
3346 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) syscall_map
;
3347 cb
->errno_map
= (CB_TARGET_DEFS_MAP
*) errno_map
;
3349 /* The kernel stat64 layout. If we see a file > 2G, the "long"
3350 parameter to cb_store_target_endian will make st_size negative.
3351 Similarly for st_ino. FIXME: Find a 64-bit type, and use it
3352 *unsigned*, and/or add syntax for signed-ness. */
3353 cb
->stat_map
= stat_map
;
3354 cb
->open_map
= (CB_TARGET_DEFS_MAP
*) open_map
;
3355 cb
->pipe_nonempty
= cris_pipe_nonempty
;
3356 cb
->pipe_empty
= cris_pipe_empty
;
3357 cb
->time
= cris_time
;
3360 /* Process an address exception. */
3363 cris_core_signal (SIM_DESC sd
, SIM_CPU
*current_cpu
, sim_cia cia
,
3364 unsigned int map
, int nr_bytes
, address_word addr
,
3365 transfer_type transfer
, sim_core_signals sig
)
3367 sim_core_signal (sd
, current_cpu
, cia
, map
, nr_bytes
, addr
,