]> Git Repo - binutils.git/blob - sim/cris/traps.c
Automatic date update in version.in
[binutils.git] / sim / cris / traps.c
1 /* CRIS exception, interrupt, and trap (EIT) support
2    Copyright (C) 2004-2022 Free Software Foundation, Inc.
3    Contributed by Axis Communications.
4
5 This file is part of the GNU simulators.
6
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.
11
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.
16
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/>.  */
19
20 /* This must come before any other includes.  */
21 #include "defs.h"
22
23 #include "portability.h"
24 #include "sim-main.h"
25 #include "sim-syscall.h"
26 #include "sim-options.h"
27 #include "sim-signal.h"
28 #include "sim/callback.h"
29 #include "bfd.h"
30 /* FIXME: get rid of targ-vals.h usage everywhere else.  */
31
32 #include <stdlib.h>
33 #include <stdarg.h>
34 #include <errno.h>
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38 #ifdef HAVE_FCNTL_H
39 #include <fcntl.h>
40 #endif
41 #ifdef HAVE_SYS_PARAM_H
42 #include <sys/param.h>
43 #endif
44 #ifdef HAVE_SYS_STAT_H
45 #include <sys/stat.h>
46 #endif
47 /* For PATH_MAX, originally. */
48 #ifdef HAVE_LIMITS_H
49 #include <limits.h>
50 #endif
51
52 /* From ld/sysdep.h.  */
53 #ifdef PATH_MAX
54 # define SIM_PATHMAX PATH_MAX
55 #else
56 # ifdef MAXPATHLEN
57 #  define SIM_PATHMAX MAXPATHLEN
58 # else
59 #  define SIM_PATHMAX 1024
60 # endif
61 #endif
62
63 /* The verbatim values are from asm-cris/unistd.h.  */
64
65 #define TARGET_SYS_exit 1
66 #define TARGET_SYS_read 3
67 #define TARGET_SYS_write 4
68 #define TARGET_SYS_open 5
69 #define TARGET_SYS_close 6
70 #define TARGET_SYS_unlink 10
71 #define TARGET_SYS_time 13
72 #define TARGET_SYS_lseek 19
73 #define TARGET_SYS_getpid 20
74 #define TARGET_SYS_access 33
75 #define TARGET_SYS_kill 37
76 #define TARGET_SYS_rename 38
77 #define TARGET_SYS_pipe 42
78 #define TARGET_SYS_brk 45
79 #define TARGET_SYS_ioctl 54
80 #define TARGET_SYS_fcntl 55
81 #define TARGET_SYS_getppid 64
82 #define TARGET_SYS_setrlimit 75
83 #define TARGET_SYS_gettimeofday  78
84 #define TARGET_SYS_readlink 85
85 #define TARGET_SYS_munmap 91
86 #define TARGET_SYS_truncate 92
87 #define TARGET_SYS_ftruncate 93
88 #define TARGET_SYS_socketcall 102
89 #define TARGET_SYS_stat 106
90 #define TARGET_SYS_fstat 108
91 #define TARGET_SYS_wait4 114
92 #define TARGET_SYS_sigreturn 119
93 #define TARGET_SYS_clone 120
94 #define TARGET_SYS_uname 122
95 #define TARGET_SYS_mprotect 125
96 #define TARGET_SYS_llseek 140
97 #define TARGET_SYS_writev 146
98 #define TARGET_SYS__sysctl 149
99 #define TARGET_SYS_sched_setparam 154
100 #define TARGET_SYS_sched_getparam 155
101 #define TARGET_SYS_sched_setscheduler 156
102 #define TARGET_SYS_sched_getscheduler 157
103 #define TARGET_SYS_sched_yield 158
104 #define TARGET_SYS_sched_get_priority_max 159
105 #define TARGET_SYS_sched_get_priority_min 160
106 #define TARGET_SYS_mremap 163
107 #define TARGET_SYS_poll 168
108 #define TARGET_SYS_rt_sigaction 174
109 #define TARGET_SYS_rt_sigprocmask 175
110 #define TARGET_SYS_rt_sigsuspend 179
111 #define TARGET_SYS_getcwd 183
112 #define TARGET_SYS_ugetrlimit 191
113 #define TARGET_SYS_mmap2 192
114 #define TARGET_SYS_stat64 195
115 #define TARGET_SYS_lstat64 196
116 #define TARGET_SYS_fstat64 197
117 #define TARGET_SYS_geteuid32 201
118 #define TARGET_SYS_getuid32 199
119 #define TARGET_SYS_getegid32 202
120 #define TARGET_SYS_getgid32 200
121 #define TARGET_SYS_fcntl64 221
122 #define TARGET_SYS_set_thread_area 243
123 #define TARGET_SYS_exit_group 252
124
125 #define TARGET_PROT_READ        0x1
126 #define TARGET_PROT_WRITE       0x2
127 #define TARGET_PROT_EXEC        0x4
128 #define TARGET_PROT_NONE        0x0
129
130 #define TARGET_MAP_SHARED       0x01
131 #define TARGET_MAP_PRIVATE      0x02
132 #define TARGET_MAP_TYPE         0x0f
133 #define TARGET_MAP_FIXED        0x10
134 #define TARGET_MAP_ANONYMOUS    0x20
135 #define TARGET_MAP_DENYWRITE    0x800
136
137 #define TARGET_CTL_KERN         1
138 #define TARGET_CTL_VM           2
139 #define TARGET_CTL_NET          3
140 #define TARGET_CTL_PROC         4
141 #define TARGET_CTL_FS           5
142 #define TARGET_CTL_DEBUG        6
143 #define TARGET_CTL_DEV          7
144 #define TARGET_CTL_BUS          8
145 #define TARGET_CTL_ABI          9
146
147 #define TARGET_CTL_KERN_VERSION 4
148
149 /* linux/mman.h */
150 #define TARGET_MREMAP_MAYMOVE  1
151 #define TARGET_MREMAP_FIXED    2
152
153 #define TARGET_TCGETS 0x5401
154
155 #define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
156
157 /* Seconds since 1970-01-01 to the above date + 10 minutes;
158    'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'.  */
159 #define TARGET_EPOCH 1230764410
160
161 /* Milliseconds since start of run.  We use the number of syscalls to
162    avoid introducing noise in the execution time.  */
163 #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
164
165 /* Seconds as in time(2).  */
166 #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
167
168 #define TARGET_SCHED_OTHER 0
169
170 #define TARGET_RLIMIT_STACK 3
171 #define TARGET_RLIMIT_NOFILE 7
172
173 #define SIM_TARGET_MAX_THREADS 64
174 #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
175
176 /* From linux/sched.h.  */
177 #define TARGET_CSIGNAL 0x000000ff
178 #define TARGET_CLONE_VM 0x00000100
179 #define TARGET_CLONE_FS 0x00000200
180 #define TARGET_CLONE_FILES 0x00000400
181 #define TARGET_CLONE_SIGHAND 0x00000800
182 #define TARGET_CLONE_PID 0x00001000
183 #define TARGET_CLONE_PTRACE 0x00002000
184 #define TARGET_CLONE_VFORK 0x00004000
185 #define TARGET_CLONE_PARENT 0x00008000
186 #define TARGET_CLONE_THREAD 0x00010000
187 #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
188
189 /* From asm-cris/poll.h.  */
190 #define TARGET_POLLIN 1
191
192 /* From asm-cris/signal.h.  */
193 #define TARGET_SIG_BLOCK 0
194 #define TARGET_SIG_UNBLOCK 1
195 #define TARGET_SIG_SETMASK 2
196
197 #define TARGET_SIG_DFL 0
198 #define TARGET_SIG_IGN 1
199 #define TARGET_SIG_ERR ((USI)-1)
200
201 #define TARGET_SIGHUP 1
202 #define TARGET_SIGINT 2
203 #define TARGET_SIGQUIT 3
204 #define TARGET_SIGILL 4
205 #define TARGET_SIGTRAP 5
206 #define TARGET_SIGABRT 6
207 #define TARGET_SIGIOT 6
208 #define TARGET_SIGBUS 7
209 #define TARGET_SIGFPE 8
210 #define TARGET_SIGKILL 9
211 #define TARGET_SIGUSR1 10
212 #define TARGET_SIGSEGV 11
213 #define TARGET_SIGUSR2 12
214 #define TARGET_SIGPIPE 13
215 #define TARGET_SIGALRM 14
216 #define TARGET_SIGTERM 15
217 #define TARGET_SIGSTKFLT 16
218 #define TARGET_SIGCHLD 17
219 #define TARGET_SIGCONT 18
220 #define TARGET_SIGSTOP 19
221 #define TARGET_SIGTSTP 20
222 #define TARGET_SIGTTIN 21
223 #define TARGET_SIGTTOU 22
224 #define TARGET_SIGURG 23
225 #define TARGET_SIGXCPU 24
226 #define TARGET_SIGXFSZ 25
227 #define TARGET_SIGVTALRM 26
228 #define TARGET_SIGPROF 27
229 #define TARGET_SIGWINCH 28
230 #define TARGET_SIGIO 29
231 #define TARGET_SIGPOLL SIGIO
232 /* Actually commented out in the kernel header.  */
233 #define TARGET_SIGLOST 29
234 #define TARGET_SIGPWR 30
235 #define TARGET_SIGSYS 31
236
237 /* From include/asm-cris/signal.h.  */
238 #define TARGET_SA_NOCLDSTOP 0x00000001
239 #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
240 #define TARGET_SA_SIGINFO 0x00000004
241 #define TARGET_SA_ONSTACK 0x08000000
242 #define TARGET_SA_RESTART 0x10000000
243 #define TARGET_SA_NODEFER 0x40000000
244 #define TARGET_SA_RESETHAND 0x80000000
245 #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
246 #define TARGET_SA_RESTORER 0x04000000
247
248 /* From linux/wait.h.  */
249 #define TARGET_WNOHANG 1
250 #define TARGET_WUNTRACED 2
251 #define TARGET___WNOTHREAD 0x20000000
252 #define TARGET___WALL 0x40000000
253 #define TARGET___WCLONE 0x80000000
254
255 /* From linux/limits.h. */
256 #define TARGET_PIPE_BUF 4096
257
258 /* From unistd.h.  */
259 #define TARGET_R_OK 4
260 #define TARGET_W_OK 2
261 #define TARGET_X_OK 1
262 #define TARGET_F_OK 0
263
264 static const char stat_map[] =
265 "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
266 ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
267 ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
268 ":st_ino,8";
269
270 static const CB_TARGET_DEFS_MAP syscall_map[] =
271 {
272   { "open", CB_SYS_open, TARGET_SYS_open },
273   { "close", CB_SYS_close, TARGET_SYS_close },
274   { "read", CB_SYS_read, TARGET_SYS_read },
275   { "write", CB_SYS_write, TARGET_SYS_write },
276   { "lseek", CB_SYS_lseek, TARGET_SYS_lseek },
277   { "unlink", CB_SYS_unlink, TARGET_SYS_unlink },
278   { "getpid", CB_SYS_getpid, TARGET_SYS_getpid },
279   { "fstat", CB_SYS_fstat, TARGET_SYS_fstat64 },
280   { "lstat", CB_SYS_lstat, TARGET_SYS_lstat64 },
281   { "stat", CB_SYS_stat, TARGET_SYS_stat64 },
282   { "pipe", CB_SYS_pipe, TARGET_SYS_pipe },
283   { "rename", CB_SYS_rename, TARGET_SYS_rename },
284   { "truncate", CB_SYS_truncate, TARGET_SYS_truncate },
285   { "ftruncate", CB_SYS_ftruncate, TARGET_SYS_ftruncate },
286   { 0, -1, -1 }
287 };
288
289 /* An older, 32-bit-only stat mapping.  */
290 static const char stat32_map[] =
291 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
292 ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
293 ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
294
295 /* Map for calls using the 32-bit struct stat.  Primarily used by the
296    newlib Linux mapping.  */
297 static const CB_TARGET_DEFS_MAP syscall_stat32_map[] =
298 {
299   { "fstat", CB_SYS_fstat, TARGET_SYS_fstat },
300   { "stat", CB_SYS_stat, TARGET_SYS_stat },
301   { 0, -1, -1 }
302 };
303
304 /* Giving the true value for the running sim process will lead to
305    non-time-invariant behavior.  */
306 #define TARGET_PID 42
307
308 /* Unfortunately, we don't get this from cris.cpu at the moment, and if
309    we did, we'd still don't get a register number with the "16" offset.  */
310 #define TARGET_SRP_REGNUM (16+11)
311
312 /* Extracted by applying
313    awk '/^#define/ { printf "#ifdef %s\n  { %s, %s },\n#endif\n", $2, $2, $3;}'
314    on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
315    adjusting the synonyms.  */
316
317 static const CB_TARGET_DEFS_MAP errno_map[] =
318 {
319 #ifdef EPERM
320   { "EPERM", EPERM, 1 },
321 #endif
322 #ifdef ENOENT
323   { "ENOENT", ENOENT, 2 },
324 #endif
325 #ifdef ESRCH
326   { "ESRCH", ESRCH, 3 },
327 #endif
328 #ifdef EINTR
329   { "EINTR", EINTR, 4 },
330 #endif
331 #ifdef EIO
332   { "EIO", EIO, 5 },
333 #endif
334 #ifdef ENXIO
335   { "ENXIO", ENXIO, 6 },
336 #endif
337 #ifdef E2BIG
338   { "E2BIG", E2BIG, 7 },
339 #endif
340 #ifdef ENOEXEC
341   { "ENOEXEC", ENOEXEC, 8 },
342 #endif
343 #ifdef EBADF
344   { "EBADF", EBADF, 9 },
345 #endif
346 #ifdef ECHILD
347   { "ECHILD", ECHILD, 10 },
348 #endif
349 #ifdef EAGAIN
350   { "EAGAIN", EAGAIN, 11 },
351 #endif
352 #ifdef ENOMEM
353   { "ENOMEM", ENOMEM, 12 },
354 #endif
355 #ifdef EACCES
356   { "EACCES", EACCES, 13 },
357 #endif
358 #ifdef EFAULT
359   { "EFAULT", EFAULT, 14 },
360 #endif
361 #ifdef ENOTBLK
362   { "ENOTBLK", ENOTBLK, 15 },
363 #endif
364 #ifdef EBUSY
365   { "EBUSY", EBUSY, 16 },
366 #endif
367 #ifdef EEXIST
368   { "EEXIST", EEXIST, 17 },
369 #endif
370 #ifdef EXDEV
371   { "EXDEV", EXDEV, 18 },
372 #endif
373 #ifdef ENODEV
374   { "ENODEV", ENODEV, 19 },
375 #endif
376 #ifdef ENOTDIR
377   { "ENOTDIR", ENOTDIR, 20 },
378 #endif
379 #ifdef EISDIR
380   { "EISDIR", EISDIR, 21 },
381 #endif
382 #ifdef EINVAL
383   { "EINVAL", EINVAL, 22 },
384 #endif
385 #ifdef ENFILE
386   { "ENFILE", ENFILE, 23 },
387 #endif
388 #ifdef EMFILE
389   { "EMFILE", EMFILE, 24 },
390 #endif
391 #ifdef ENOTTY
392   { "ENOTTY", ENOTTY, 25 },
393 #endif
394 #ifdef ETXTBSY
395   { "ETXTBSY", ETXTBSY, 26 },
396 #endif
397 #ifdef EFBIG
398   { "EFBIG", EFBIG, 27 },
399 #endif
400 #ifdef ENOSPC
401   { "ENOSPC", ENOSPC, 28 },
402 #endif
403 #ifdef ESPIPE
404   { "ESPIPE", ESPIPE, 29 },
405 #endif
406 #ifdef EROFS
407   { "EROFS", EROFS, 30 },
408 #endif
409 #ifdef EMLINK
410   { "EMLINK", EMLINK, 31 },
411 #endif
412 #ifdef EPIPE
413   { "EPIPE", EPIPE, 32 },
414 #endif
415 #ifdef EDOM
416   { "EDOM", EDOM, 33 },
417 #endif
418 #ifdef ERANGE
419   { "ERANGE", ERANGE, 34 },
420 #endif
421 #ifdef EDEADLK
422   { "EDEADLK", EDEADLK, 35 },
423 #endif
424 #ifdef ENAMETOOLONG
425   { "ENAMETOOLONG", ENAMETOOLONG, 36 },
426 #endif
427 #ifdef ENOLCK
428   { "ENOLCK", ENOLCK, 37 },
429 #endif
430 #ifdef ENOSYS
431   { "ENOSYS", ENOSYS, 38 },
432 #endif
433 #ifdef ENOTEMPTY
434   { "ENOTEMPTY", ENOTEMPTY, 39 },
435 #endif
436 #ifdef ELOOP
437   { "ELOOP", ELOOP, 40 },
438 #endif
439 #ifdef EWOULDBLOCK
440   { "EWOULDBLOCK", EWOULDBLOCK, 11 },
441 #endif
442 #ifdef ENOMSG
443   { "ENOMSG", ENOMSG, 42 },
444 #endif
445 #ifdef EIDRM
446   { "EIDRM", EIDRM, 43 },
447 #endif
448 #ifdef ECHRNG
449   { "ECHRNG", ECHRNG, 44 },
450 #endif
451 #ifdef EL2NSYNC
452   { "EL2NSYNC", EL2NSYNC, 45 },
453 #endif
454 #ifdef EL3HLT
455   { "EL3HLT", EL3HLT, 46 },
456 #endif
457 #ifdef EL3RST
458   { "EL3RST", EL3RST, 47 },
459 #endif
460 #ifdef ELNRNG
461   { "ELNRNG", ELNRNG, 48 },
462 #endif
463 #ifdef EUNATCH
464   { "EUNATCH", EUNATCH, 49 },
465 #endif
466 #ifdef ENOCSI
467   { "ENOCSI", ENOCSI, 50 },
468 #endif
469 #ifdef EL2HLT
470   { "EL2HLT", EL2HLT, 51 },
471 #endif
472 #ifdef EBADE
473   { "EBADE", EBADE, 52 },
474 #endif
475 #ifdef EBADR
476   { "EBADR", EBADR, 53 },
477 #endif
478 #ifdef EXFULL
479   { "EXFULL", EXFULL, 54 },
480 #endif
481 #ifdef ENOANO
482   { "ENOANO", ENOANO, 55 },
483 #endif
484 #ifdef EBADRQC
485   { "EBADRQC", EBADRQC, 56 },
486 #endif
487 #ifdef EBADSLT
488   { "EBADSLT", EBADSLT, 57 },
489 #endif
490 #ifdef EDEADLOCK
491   { "EDEADLOCK", EDEADLOCK, 35 },
492 #endif
493 #ifdef EBFONT
494   { "EBFONT", EBFONT, 59 },
495 #endif
496 #ifdef ENOSTR
497   { "ENOSTR", ENOSTR, 60 },
498 #endif
499 #ifdef ENODATA
500   { "ENODATA", ENODATA, 61 },
501 #endif
502 #ifdef ETIME
503   { "ETIME", ETIME, 62 },
504 #endif
505 #ifdef ENOSR
506   { "ENOSR", ENOSR, 63 },
507 #endif
508 #ifdef ENONET
509   { "ENONET", ENONET, 64 },
510 #endif
511 #ifdef ENOPKG
512   { "ENOPKG", ENOPKG, 65 },
513 #endif
514 #ifdef EREMOTE
515   { "EREMOTE", EREMOTE, 66 },
516 #endif
517 #ifdef ENOLINK
518   { "ENOLINK", ENOLINK, 67 },
519 #endif
520 #ifdef EADV
521   { "EADV", EADV, 68 },
522 #endif
523 #ifdef ESRMNT
524   { "ESRMNT", ESRMNT, 69 },
525 #endif
526 #ifdef ECOMM
527   { "ECOMM", ECOMM, 70 },
528 #endif
529 #ifdef EPROTO
530   { "EPROTO", EPROTO, 71 },
531 #endif
532 #ifdef EMULTIHOP
533   { "EMULTIHOP", EMULTIHOP, 72 },
534 #endif
535 #ifdef EDOTDOT
536   { "EDOTDOT", EDOTDOT, 73 },
537 #endif
538 #ifdef EBADMSG
539   { "EBADMSG", EBADMSG, 74 },
540 #endif
541 #ifdef EOVERFLOW
542   { "EOVERFLOW", EOVERFLOW, 75 },
543 #endif
544 #ifdef ENOTUNIQ
545   { "ENOTUNIQ", ENOTUNIQ, 76 },
546 #endif
547 #ifdef EBADFD
548   { "EBADFD", EBADFD, 77 },
549 #endif
550 #ifdef EREMCHG
551   { "EREMCHG", EREMCHG, 78 },
552 #endif
553 #ifdef ELIBACC
554   { "ELIBACC", ELIBACC, 79 },
555 #endif
556 #ifdef ELIBBAD
557   { "ELIBBAD", ELIBBAD, 80 },
558 #endif
559 #ifdef ELIBSCN
560   { "ELIBSCN", ELIBSCN, 81 },
561 #endif
562 #ifdef ELIBMAX
563   { "ELIBMAX", ELIBMAX, 82 },
564 #endif
565 #ifdef ELIBEXEC
566   { "ELIBEXEC", ELIBEXEC, 83 },
567 #endif
568 #ifdef EILSEQ
569   { "EILSEQ", EILSEQ, 84 },
570 #endif
571 #ifdef ERESTART
572   { "ERESTART", ERESTART, 85 },
573 #endif
574 #ifdef ESTRPIPE
575   { "ESTRPIPE", ESTRPIPE, 86 },
576 #endif
577 #ifdef EUSERS
578   { "EUSERS", EUSERS, 87 },
579 #endif
580 #ifdef ENOTSOCK
581   { "ENOTSOCK", ENOTSOCK, 88 },
582 #endif
583 #ifdef EDESTADDRREQ
584   { "EDESTADDRREQ", EDESTADDRREQ, 89 },
585 #endif
586 #ifdef EMSGSIZE
587   { "EMSGSIZE", EMSGSIZE, 90 },
588 #endif
589 #ifdef EPROTOTYPE
590   { "EPROTOTYPE", EPROTOTYPE, 91 },
591 #endif
592 #ifdef ENOPROTOOPT
593   { "ENOPROTOOPT", ENOPROTOOPT, 92 },
594 #endif
595 #ifdef EPROTONOSUPPORT
596   { "EPROTONOSUPPORT", EPROTONOSUPPORT, 93 },
597 #endif
598 #ifdef ESOCKTNOSUPPORT
599   { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, 94 },
600 #endif
601 #ifdef EOPNOTSUPP
602   { "EOPNOTSUPP", EOPNOTSUPP, 95 },
603 #endif
604 #ifdef EPFNOSUPPORT
605   { "EPFNOSUPPORT", EPFNOSUPPORT, 96 },
606 #endif
607 #ifdef EAFNOSUPPORT
608   { "EAFNOSUPPORT", EAFNOSUPPORT, 97 },
609 #endif
610 #ifdef EADDRINUSE
611   { "EADDRINUSE", EADDRINUSE, 98 },
612 #endif
613 #ifdef EADDRNOTAVAIL
614   { "EADDRNOTAVAIL", EADDRNOTAVAIL, 99 },
615 #endif
616 #ifdef ENETDOWN
617   { "ENETDOWN", ENETDOWN, 100 },
618 #endif
619 #ifdef ENETUNREACH
620   { "ENETUNREACH", ENETUNREACH, 101 },
621 #endif
622 #ifdef ENETRESET
623   { "ENETRESET", ENETRESET, 102 },
624 #endif
625 #ifdef ECONNABORTED
626   { "ECONNABORTED", ECONNABORTED, 103 },
627 #endif
628 #ifdef ECONNRESET
629   { "ECONNRESET", ECONNRESET, 104 },
630 #endif
631 #ifdef ENOBUFS
632   { "ENOBUFS", ENOBUFS, 105 },
633 #endif
634 #ifdef EISCONN
635   { "EISCONN", EISCONN, 106 },
636 #endif
637 #ifdef ENOTCONN
638   { "ENOTCONN", ENOTCONN, 107 },
639 #endif
640 #ifdef ESHUTDOWN
641   { "ESHUTDOWN", ESHUTDOWN, 108 },
642 #endif
643 #ifdef ETOOMANYREFS
644   { "ETOOMANYREFS", ETOOMANYREFS, 109 },
645 #endif
646 #ifdef ETIMEDOUT
647   { "ETIMEDOUT", ETIMEDOUT, 110 },
648 #endif
649 #ifdef ECONNREFUSED
650   { "ECONNREFUSED", ECONNREFUSED, 111 },
651 #endif
652 #ifdef EHOSTDOWN
653   { "EHOSTDOWN", EHOSTDOWN, 112 },
654 #endif
655 #ifdef EHOSTUNREACH
656   { "EHOSTUNREACH", EHOSTUNREACH, 113 },
657 #endif
658 #ifdef EALREADY
659   { "EALREADY", EALREADY, 114 },
660 #endif
661 #ifdef EINPROGRESS
662   { "EINPROGRESS", EINPROGRESS, 115 },
663 #endif
664 #ifdef ESTALE
665   { "ESTALE", ESTALE, 116 },
666 #endif
667 #ifdef EUCLEAN
668   { "EUCLEAN", EUCLEAN, 117 },
669 #endif
670 #ifdef ENOTNAM
671   { "ENOTNAM", ENOTNAM, 118 },
672 #endif
673 #ifdef ENAVAIL
674   { "ENAVAIL", ENAVAIL, 119 },
675 #endif
676 #ifdef EISNAM
677   { "EISNAM", EISNAM, 120 },
678 #endif
679 #ifdef EREMOTEIO
680   { "EREMOTEIO", EREMOTEIO, 121 },
681 #endif
682 #ifdef EDQUOT
683   { "EDQUOT", EDQUOT, 122 },
684 #endif
685 #ifdef ENOMEDIUM
686   { "ENOMEDIUM", ENOMEDIUM, 123 },
687 #endif
688 #ifdef EMEDIUMTYPE
689   { "EMEDIUMTYPE", EMEDIUMTYPE, 124 },
690 #endif
691   { 0, 0, 0 }
692 };
693
694 /* Extracted by applying
695    perl -ne 'if ($_ =~ /^#define/) { split;
696      printf "#ifdef $_[1]\n  { %s, 0x%x },\n#endif\n",
697              $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
698    on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
699    installation and removing synonyms and unnecessary items.  Don't
700    forget the end-marker.  */
701
702 /* These we treat specially, as they're used in the fcntl F_GETFL
703    syscall.  For consistency, open_map is also manually edited to use
704    these macros.  */
705 #define TARGET_O_ACCMODE 0x3
706 #define TARGET_O_RDONLY 0x0
707 #define TARGET_O_WRONLY 0x1
708
709 static const CB_TARGET_DEFS_MAP open_map[] = {
710 #ifdef O_ACCMODE
711   { "O_ACCMODE", O_ACCMODE, TARGET_O_ACCMODE },
712 #endif
713 #ifdef O_RDONLY
714   { "O_RDONLY", O_RDONLY, TARGET_O_RDONLY },
715 #endif
716 #ifdef O_WRONLY
717   { "O_WRONLY", O_WRONLY, TARGET_O_WRONLY },
718 #endif
719 #ifdef O_RDWR
720   { "O_RDWR", O_RDWR, 0x2 },
721 #endif
722 #ifdef O_CREAT
723   { "O_CREAT", O_CREAT, 0x40 },
724 #endif
725 #ifdef O_EXCL
726   { "O_EXCL", O_EXCL, 0x80 },
727 #endif
728 #ifdef O_NOCTTY
729   { "O_NOCTTY", O_NOCTTY, 0x100 },
730 #endif
731 #ifdef O_TRUNC
732   { "O_TRUNC", O_TRUNC, 0x200 },
733 #endif
734 #ifdef O_APPEND
735   { "O_APPEND", O_APPEND, 0x400 },
736 #endif
737 #ifdef O_NONBLOCK
738   { "O_NONBLOCK", O_NONBLOCK, 0x800 },
739 #endif
740 #ifdef O_NDELAY
741   { "O_NDELAY", O_NDELAY, 0x0 },
742 #endif
743 #ifdef O_SYNC
744   { "O_SYNC", O_SYNC, 0x1000 },
745 #endif
746 #ifdef FASYNC
747   { "FASYNC", FASYNC, 0x2000 },
748 #endif
749 #ifdef O_DIRECT
750   { "O_DIRECT", O_DIRECT, 0x4000 },
751 #endif
752 #ifdef O_LARGEFILE
753   { "O_LARGEFILE", O_LARGEFILE, 0x8000 },
754 #endif
755 #ifdef O_DIRECTORY
756   { "O_DIRECTORY", O_DIRECTORY, 0x10000 },
757 #endif
758 #ifdef O_NOFOLLOW
759   { "O_NOFOLLOW", O_NOFOLLOW, 0x20000 },
760 #endif
761   { 0, -1, -1 }
762 };
763
764 /* Let's be less drastic and more traceable.  FIXME: mark as noreturn.  */
765 #define abort()                                                 \
766   sim_io_error (sd, "simulator unhandled condition at %s:%d",   \
767                 __FUNCTION__, __LINE__)
768
769 /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls.  */
770 static SIM_CPU *current_cpu_for_cb_callback;
771
772 static USI create_map (SIM_DESC, struct cris_sim_mmapped_page **,
773                        USI addr, USI len);
774 static USI unmap_pages (SIM_DESC, struct cris_sim_mmapped_page **,
775                        USI addr, USI len);
776 static USI is_mapped (SIM_DESC, struct cris_sim_mmapped_page **,
777                        USI addr, USI len);
778 static void dump_statistics (SIM_CPU *current_cpu);
779 static void make_first_thread (SIM_CPU *current_cpu);
780
781 /* When we risk running self-modified code (as in trampolines), this is
782    called from special-case insns.  The silicon CRIS CPU:s have enough
783    cache snooping implemented making this a simulator-only issue.  Tests:
784    gcc.c-torture/execute/931002-1.c execution, -O3 -g
785    gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer.  */
786
787 void
788 cris_flush_simulator_decode_cache (SIM_CPU *current_cpu,
789                                    USI pc ATTRIBUTE_UNUSED)
790 {
791   SIM_DESC sd = CPU_STATE (current_cpu);
792
793 #if WITH_SCACHE
794   if (USING_SCACHE_P (sd))
795     scache_flush_cpu (current_cpu);
796 #endif
797 }
798
799 /* Output statistics at the end of a run.  */
800 static void
801 dump_statistics (SIM_CPU *current_cpu)
802 {
803   SIM_DESC sd = CPU_STATE (current_cpu);
804   CRIS_MISC_PROFILE *profp
805     = CPU_CRIS_MISC_PROFILE (current_cpu);
806   uint64_t total = profp->basic_cycle_count;
807
808   /* Historically, these messages have gone to stderr, so we'll keep it
809      that way.  It's also easier to then tell it from normal program
810      output.  FIXME: Add redirect option like "run -e file".  */
811
812   /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
813      what's included in the "total" count only.  */
814   switch (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
815           & FLAG_CRIS_MISC_PROFILE_ALL)
816     {
817     case FLAG_CRIS_MISC_PROFILE_SIMPLE:
818       sim_io_eprintf (sd, "Basic clock cycles, total @: %" PRIu64 "\n", total);
819       break;
820
821     case (FLAG_CRIS_MISC_PROFILE_UNALIGNED | FLAG_CRIS_MISC_PROFILE_SIMPLE):
822       total += profp->unaligned_mem_dword_count;
823       sim_io_eprintf (sd,
824                       "Clock cycles including stall cycles for unaligned "
825                       "accesses @: %" PRIu64 "\n",
826                       total);
827       break;
828
829     case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE | FLAG_CRIS_MISC_PROFILE_SIMPLE):
830       total
831         += (profp->memsrc_stall_count
832             + profp->memraw_stall_count
833             + profp->movemsrc_stall_count
834             + profp->movemdst_stall_count
835             + profp->mulsrc_stall_count
836             + profp->jumpsrc_stall_count
837             + profp->unaligned_mem_dword_count);
838       sim_io_eprintf (sd, "Schedulable clock cycles, total @: %" PRIu64 "\n",
839                       total);
840       break;
841
842     case FLAG_CRIS_MISC_PROFILE_ALL:
843       total
844         += (profp->memsrc_stall_count
845             + profp->memraw_stall_count
846             + profp->movemsrc_stall_count
847             + profp->movemdst_stall_count
848             + profp->movemaddr_stall_count
849             + profp->mulsrc_stall_count
850             + profp->jumpsrc_stall_count
851             + profp->branch_stall_count
852             + profp->jumptarget_stall_count
853             + profp->unaligned_mem_dword_count);
854       sim_io_eprintf (sd, "All accounted clock cycles, total @: %" PRIu64 "\n",
855                       total);
856       break;
857
858     default:
859       sim_engine_abort (sd, current_cpu, 0,
860                         "Internal inconsistency at %s:%d",
861                         __FILE__, __LINE__);
862     }
863
864   /* For v32, unaligned_mem_dword_count should always be 0.  For
865      v10, memsrc_stall_count should always be 0.  */
866   sim_io_eprintf (sd, "Memory source stall cycles: %" PRIu64 "\n",
867                   profp->memsrc_stall_count + profp->unaligned_mem_dword_count);
868   sim_io_eprintf (sd, "Memory read-after-write stall cycles: %" PRIu64 "\n",
869                   profp->memraw_stall_count);
870   sim_io_eprintf (sd, "Movem source stall cycles: %" PRIu64 "\n",
871                   profp->movemsrc_stall_count);
872   sim_io_eprintf (sd, "Movem destination stall cycles: %" PRIu64 "\n",
873                   profp->movemdst_stall_count);
874   sim_io_eprintf (sd, "Movem address stall cycles: %" PRIu64 "\n",
875                   profp->movemaddr_stall_count);
876   sim_io_eprintf (sd, "Multiplication source stall cycles: %" PRIu64 "\n",
877                   profp->mulsrc_stall_count);
878   sim_io_eprintf (sd, "Jump source stall cycles: %" PRIu64 "\n",
879                   profp->jumpsrc_stall_count);
880   sim_io_eprintf (sd, "Branch misprediction stall cycles: %" PRIu64 "\n",
881                   profp->branch_stall_count);
882   sim_io_eprintf (sd, "Jump target stall cycles: %" PRIu64 "\n",
883                   profp->jumptarget_stall_count);
884 }
885
886 /* Check whether any part of [addr .. addr + len - 1] is already mapped.
887    Return 1 if a overlap detected, 0 otherwise.  */
888
889 static USI
890 is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED,
891            struct cris_sim_mmapped_page **rootp,
892            USI addr, USI len)
893 {
894   struct cris_sim_mmapped_page *mapp;
895
896   if (len == 0 || (len & 8191))
897     abort ();
898
899   /* Iterate over the reverse-address sorted pages until we find a page in
900      or lower than the checked area.  */
901   for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
902     if (mapp->addr < addr + len && mapp->addr >= addr)
903       return 1;
904
905   return 0;
906 }
907
908 /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
909    Return 1 if the whole area is mapped, 0 otherwise.  */
910
911 static USI
912 is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED,
913                 struct cris_sim_mmapped_page **rootp,
914                 USI addr, USI len)
915 {
916   struct cris_sim_mmapped_page *mapp;
917
918   if (len == 0 || (len & 8191))
919     abort ();
920
921   /* Iterate over the reverse-address sorted pages until we find a page
922      lower than the checked area.  */
923   for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
924     if (addr == mapp->addr && len == 8192)
925       return 1;
926     else if (addr + len > mapp->addr)
927       len -= 8192;
928
929   return 0;
930 }
931
932 /* Provide a prototype to silence -Wmissing-prototypes.  */
933 void cris_dump_map (SIM_CPU *current_cpu);
934
935 /* Debug helper; to be run from gdb.  */
936 void
937 cris_dump_map (SIM_CPU *current_cpu)
938 {
939   struct cris_sim_mmapped_page *mapp;
940   USI start, end;
941
942   for (mapp = current_cpu->highest_mmapped_page,
943          start = mapp == NULL ? 0 : mapp->addr + 8192,
944          end = mapp == NULL ? 0 : mapp->addr + 8191;
945        mapp != NULL;
946        mapp = mapp->prev)
947     {
948       if (mapp->addr != start - 8192)
949         {
950           sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
951           end = mapp->addr + 8191;
952         }
953
954       start = mapp->addr;
955     }
956
957   if (current_cpu->highest_mmapped_page != NULL)
958     sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
959 }
960
961 /* Create mmapped memory.  ADDR is -1 if any address will do.  Caller
962    must make sure that the address isn't already mapped.  */
963
964 static USI
965 create_map (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
966             USI len)
967 {
968   struct cris_sim_mmapped_page *mapp;
969   struct cris_sim_mmapped_page **higher_prevp = rootp;
970   USI new_addr = 0x40000000;
971
972   if (addr != (USI) -1)
973     new_addr = addr;
974   else if (*rootp && rootp[0]->addr >= new_addr)
975     new_addr = rootp[0]->addr + 8192;
976
977   if (len != 8192)
978     {
979       USI page_addr;
980
981       if (len & 8191)
982         /* Which is better: return an error for this, or just round it up?  */
983         abort ();
984
985       /* Do a recursive call for each page in the request.  */
986       for (page_addr = new_addr; len != 0; page_addr += 8192, len -= 8192)
987         if (create_map (sd, rootp, page_addr, 8192) >= (USI) -8191)
988           abort ();
989
990       return new_addr;
991     }
992
993   for (mapp = *rootp;
994        mapp != NULL && mapp->addr > new_addr;
995        mapp = mapp->prev)
996     higher_prevp = &mapp->prev;
997
998   /* Assert for consistency that we don't create duplicate maps.  */
999   if (is_mapped (sd, rootp, new_addr, len))
1000     abort ();
1001
1002   /* Allocate the new page, on the next higher page from the last one
1003      allocated, and link in the new descriptor before previous ones.  */
1004   mapp = malloc (sizeof (*mapp));
1005
1006   if (mapp == NULL)
1007     return (USI) -ENOMEM;
1008
1009   sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
1010                    new_addr, len,
1011                    0, NULL, NULL);
1012
1013   mapp->addr = new_addr;
1014   mapp->prev = *higher_prevp;
1015   *higher_prevp = mapp;
1016
1017   return new_addr;
1018 }
1019
1020 /* Unmap one or more pages.  */
1021
1022 static USI
1023 unmap_pages (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
1024             USI len)
1025 {
1026   struct cris_sim_mmapped_page *mapp;
1027   struct cris_sim_mmapped_page **higher_prevp = rootp;
1028
1029   if (len != 8192)
1030     {
1031       USI page_addr;
1032       int ret = 0;
1033
1034       if (len & 8191)
1035         /* Which is better: return an error for this, or just round it up?  */
1036         abort ();
1037
1038       /* Loop backwards to make each call is O(1) over the number of pages
1039          allocated, if we're unmapping from the high end of the pages.  */
1040       for (page_addr = addr + len - 8192;
1041            page_addr > addr;
1042            page_addr -= 8192)
1043         if (unmap_pages (sd, rootp, page_addr, 8192))
1044           ret = EINVAL;
1045
1046       if (unmap_pages (sd, rootp, addr, 8192))
1047         ret = EINVAL;
1048
1049       return ret;
1050     }
1051
1052   for (mapp = *rootp; mapp != NULL && mapp->addr > addr; mapp = mapp->prev)
1053     higher_prevp = &mapp->prev;
1054
1055   if (mapp == NULL || mapp->addr != addr)
1056     return EINVAL;
1057
1058   *higher_prevp = mapp->prev;
1059   sim_core_detach (sd, NULL, 0, 0, addr);
1060   free (mapp);
1061   return 0;
1062 }
1063
1064 /* The semantic code invokes this for illegal (unrecognized) instructions.  */
1065
1066 SEM_PC
1067 sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
1068 {
1069   SIM_DESC sd = CPU_STATE (current_cpu);
1070
1071   sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
1072   return vpc;
1073 }
1074
1075 /* Swap one context for another.  */
1076
1077 static void
1078 schedule (SIM_CPU *current_cpu, int next)
1079 {
1080   /* Need to mark context-switches in the trace output.  */
1081   if ((CPU_CRIS_MISC_PROFILE (current_cpu)->flags
1082        & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE))
1083     cris_trace_printf (CPU_STATE (current_cpu), current_cpu,
1084                        "\t#:%d\n", next);
1085
1086   /* Copy the current context (if there is one) to its slot.  */
1087   if (current_cpu->thread_data[current_cpu->threadno].cpu_context)
1088     memcpy (current_cpu->thread_data[current_cpu->threadno].cpu_context,
1089             &current_cpu->cpu_data_placeholder,
1090             current_cpu->thread_cpu_data_size);
1091
1092   /* Copy the new context from its slot.  */
1093   memcpy (&current_cpu->cpu_data_placeholder,
1094           current_cpu->thread_data[next].cpu_context,
1095           current_cpu->thread_cpu_data_size);
1096
1097   /* Update needed stuff to indicate the new context.  */
1098   current_cpu->threadno = next;
1099
1100   /* Handle pending signals.  */
1101   if (current_cpu->thread_data[next].sigpending
1102       /* We don't run nested signal handlers.  This means that pause(2)
1103          and sigsuspend(2) do not work in sighandlers, but that
1104          shouldn't be too hard a restriction.  It also greatly
1105          simplifies the code.  */
1106       && current_cpu->thread_data[next].cpu_context_atsignal == NULL)
1107   {
1108     int sig;
1109
1110     /* See if there's really a pending, non-blocked handler.  We don't
1111        queue signals, so just use the first one in ascending order.  */
1112     for (sig = 0; sig < 64; sig++)
1113       if (current_cpu->thread_data[next].sigdata[sig].pending
1114           && !current_cpu->thread_data[next].sigdata[sig].blocked)
1115       {
1116         bfd_byte regbuf[4];
1117         USI sp;
1118         int i;
1119         USI blocked;
1120         USI pc = sim_pc_get (current_cpu);
1121
1122         /* It's simpler to save the CPU context inside the simulator
1123            than on the stack.  */
1124         current_cpu->thread_data[next].cpu_context_atsignal
1125           = (*current_cpu
1126              ->make_thread_cpu_data) (current_cpu,
1127                                       current_cpu->thread_data[next]
1128                                       .cpu_context);
1129
1130         (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
1131         sp = bfd_getl32 (regbuf);
1132
1133         /* Make sure we have an aligned stack.  */
1134         sp &= ~3;
1135
1136         /* Make room for the signal frame, aligned.  FIXME: Check that
1137            the memory exists, map it in if absent.  (BTW, should also
1138            implement on-access automatic stack allocation).  */
1139         sp -= 20;
1140
1141         /* This isn't the same signal frame as the kernel uses, because
1142            we don't want to bother getting all registers on and off the
1143            stack.  */
1144
1145         /* First, we store the currently blocked signals.  */
1146         blocked = 0;
1147         for (i = 0; i < 32; i++)
1148           blocked
1149             |= current_cpu->thread_data[next].sigdata[i + 1].blocked << i;
1150         sim_core_write_aligned_4 (current_cpu, pc, 0, sp, blocked);
1151         blocked = 0;
1152         for (i = 0; i < 31; i++)
1153           blocked
1154             |= current_cpu->thread_data[next].sigdata[i + 33].blocked << i;
1155         sim_core_write_aligned_4 (current_cpu, pc, 0, sp + 4, blocked);
1156
1157         /* Then, the actual instructions.  This is CPU-specific, but we
1158            use instructions from the common subset for v10 and v32 which
1159            should be safe for the time being but could be parametrized
1160            if need be.  */
1161         /* MOVU.W [PC+],R9.  */
1162         sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 8, 0x9c5f);
1163         /* .WORD TARGET_SYS_sigreturn.  */
1164         sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 10,
1165                                   TARGET_SYS_sigreturn);
1166         /* BREAK 13.  */
1167         sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 12, 0xe93d);
1168
1169         /* NOP (on v32; it's SETF on v10, but is the correct compatible
1170            instruction.  Still, it doesn't matter because v10 has no
1171            delay slot for BREAK so it will not be executed).  */
1172         sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 16, 0x05b0);
1173
1174         /* Modify registers to hold the right values for the sighandler
1175            context: updated stackpointer and return address pointing to
1176            the sigreturn stub.  */
1177         bfd_putl32 (sp, regbuf);
1178         (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
1179         bfd_putl32 (sp + 8, regbuf);
1180         (*CPU_REG_STORE (current_cpu)) (current_cpu, TARGET_SRP_REGNUM,
1181                                         regbuf, 4);
1182
1183         current_cpu->thread_data[next].sigdata[sig].pending = 0;
1184
1185         /* Block this signal (for the duration of the sighandler).  */
1186         current_cpu->thread_data[next].sigdata[sig].blocked = 1;
1187
1188         sim_pc_set (current_cpu, current_cpu->sighandler[sig]);
1189         bfd_putl32 (sig, regbuf);
1190         (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10,
1191                                         regbuf, 4);
1192
1193         /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
1194            needed all this for, specifies a SA_SIGINFO call but treats it
1195            like an ordinary sighandler; only the signal number argument is
1196            inspected.  To make future need to implement SA_SIGINFO
1197            correctly possible, we set the siginfo argument register to a
1198            magic (hopefully non-address) number.  (NB: then, you should
1199            just need to pass the siginfo argument; it seems you probably
1200            don't need to implement the specific rt_sigreturn.)  */
1201         bfd_putl32 (0xbad5161f, regbuf);
1202         (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R11,
1203                                         regbuf, 4);
1204
1205         /* The third argument is unused and the kernel sets it to 0.  */
1206         bfd_putl32 (0, regbuf);
1207         (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R12,
1208                                         regbuf, 4);
1209         return;
1210       }
1211
1212     /* No, there actually was no pending signal for this thread.  Reset
1213        this flag.  */
1214     current_cpu->thread_data[next].sigpending = 0;
1215   }
1216 }
1217
1218 /* Reschedule the simplest possible way until something else is absolutely
1219    necessary:
1220    - A. Find the next process (round-robin) that doesn't have at_syscall
1221         set, schedule it.
1222    - B. If there is none, just run the next process, round-robin.
1223    - Clear at_syscall for the current process.  */
1224
1225 static void
1226 reschedule (SIM_CPU *current_cpu)
1227 {
1228   SIM_DESC sd = CPU_STATE (current_cpu);
1229   int i;
1230
1231   /* Iterate over all thread slots, because after a few thread creations
1232      and exits, we don't know where the live ones are.  */
1233   for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
1234        i != current_cpu->threadno;
1235        i = (i + 1) % SIM_TARGET_MAX_THREADS)
1236     if (current_cpu->thread_data[i].cpu_context
1237         && current_cpu->thread_data[i].at_syscall == 0)
1238       {
1239         schedule (current_cpu, i);
1240         return;
1241       }
1242
1243   /* Pick any next live thread.  */
1244   for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
1245        i != current_cpu->threadno;
1246        i = (i + 1) % SIM_TARGET_MAX_THREADS)
1247     if (current_cpu->thread_data[i].cpu_context)
1248       {
1249         schedule (current_cpu, i);
1250         return;
1251       }
1252
1253   /* More than one live thread, but we couldn't find the next one?  */
1254   abort ();
1255 }
1256
1257 /* Set up everything to receive (or IGN) an incoming signal to the
1258    current context.  */
1259
1260 static int
1261 deliver_signal (SIM_CPU *current_cpu, int sig, unsigned int pid)
1262 {
1263   int i;
1264   USI pc = sim_pc_get (current_cpu);
1265
1266   /* Find the thread index of the pid. */
1267   for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
1268     /* Apparently it's ok to send signals to zombies (so a check for
1269        current_cpu->thread_data[i].cpu_context != NULL would be
1270        wrong). */
1271     if (current_cpu->thread_data[i].threadid == pid - TARGET_PID)
1272       {
1273         if (sig < 64)
1274           switch (current_cpu->sighandler[sig])
1275             {
1276             case TARGET_SIG_DFL:
1277               switch (sig)
1278                 {
1279                   /* The following according to the glibc
1280                      documentation. (The kernel code has non-obvious
1281                      execution paths.)  */
1282                 case TARGET_SIGFPE:
1283                 case TARGET_SIGILL:
1284                 case TARGET_SIGSEGV:
1285                 case TARGET_SIGBUS:
1286                 case TARGET_SIGABRT:
1287                 case TARGET_SIGTRAP:
1288                 case TARGET_SIGSYS:
1289
1290                 case TARGET_SIGTERM:
1291                 case TARGET_SIGINT:
1292                 case TARGET_SIGQUIT:
1293                 case TARGET_SIGKILL:
1294                 case TARGET_SIGHUP:
1295
1296                 case TARGET_SIGALRM:
1297                 case TARGET_SIGVTALRM:
1298                 case TARGET_SIGPROF:
1299                 case TARGET_SIGSTOP:
1300
1301                 case TARGET_SIGPIPE:
1302                 case TARGET_SIGLOST:
1303                 case TARGET_SIGXCPU:
1304                 case TARGET_SIGXFSZ:
1305                 case TARGET_SIGUSR1:
1306                 case TARGET_SIGUSR2:
1307                   sim_io_eprintf (CPU_STATE (current_cpu),
1308                                   "Exiting pid %d due to signal %d\n",
1309                                   pid, sig);
1310                   sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
1311                                    NULL, pc, sim_stopped,
1312                                    sig == TARGET_SIGABRT
1313                                    ? SIM_SIGABRT : SIM_SIGILL);
1314                   return 0;
1315
1316                   /* The default for all other signals is to be ignored.  */
1317                 default:
1318                   return 0;
1319                 }
1320
1321             case TARGET_SIG_IGN:
1322               switch (sig)
1323                 {
1324                 case TARGET_SIGKILL:
1325                 case TARGET_SIGSTOP:
1326                   /* Can't ignore these signals.  */
1327                   sim_io_eprintf (CPU_STATE (current_cpu),
1328                                   "Exiting pid %d due to signal %d\n",
1329                                   pid, sig);
1330                   sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
1331                                    NULL, pc, sim_stopped, SIM_SIGILL);
1332                   return 0;
1333
1334                 default:
1335                   return 0;
1336                 }
1337               break;
1338
1339             default:
1340               /* Mark the signal as pending, making schedule () check
1341                  closer.  The signal will be handled when the thread is
1342                  scheduled and the signal is unblocked.  */
1343               current_cpu->thread_data[i].sigdata[sig].pending = 1;
1344               current_cpu->thread_data[i].sigpending = 1;
1345               return 0;
1346             }
1347         else
1348           {
1349             sim_io_eprintf (CPU_STATE (current_cpu),
1350                             "Unimplemented signal: %d\n", sig);
1351             sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc,
1352                              sim_stopped, SIM_SIGILL);
1353           }
1354       }
1355
1356   return
1357     -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu)),
1358                               ESRCH);
1359 }
1360
1361 /* Make the vector and the first item, the main thread.  */
1362
1363 static void
1364 make_first_thread (SIM_CPU *current_cpu)
1365 {
1366   SIM_DESC sd = CPU_STATE (current_cpu);
1367   current_cpu->thread_data
1368     = xcalloc (1,
1369                SIM_TARGET_MAX_THREADS
1370                * sizeof (current_cpu->thread_data[0]));
1371   current_cpu->thread_data[0].cpu_context
1372     = (*current_cpu->make_thread_cpu_data) (current_cpu,
1373                                             &current_cpu
1374                                             ->cpu_data_placeholder);
1375   current_cpu->thread_data[0].parent_threadid = -1;
1376
1377   /* For good measure.  */
1378   if (TARGET_SIG_DFL != 0)
1379     abort ();
1380 }
1381
1382 /* Handle unknown system calls.  Returns (if it does) the syscall
1383    return value.  */
1384
1385 static USI ATTRIBUTE_PRINTF (3, 4)
1386 cris_unknown_syscall (SIM_CPU *current_cpu, USI pc, char *s, ...)
1387 {
1388   SIM_DESC sd = CPU_STATE (current_cpu);
1389   host_callback *cb = STATE_CALLBACK (sd);
1390
1391   if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP
1392       || cris_unknown_syscall_action == CRIS_USYSC_MSG_ENOSYS)
1393     {
1394       va_list ap;
1395
1396       va_start (ap, s);
1397       sim_io_evprintf (sd, s, ap);
1398       va_end (ap);
1399
1400       if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP)
1401         sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
1402     }
1403
1404   return -cb_host_to_target_errno (cb, ENOSYS);
1405 }
1406
1407 /* Main function: the handler of the "break 13" syscall insn.  */
1408
1409 USI
1410 cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
1411                        USI arg2, USI arg3, USI arg4, USI arg5, USI arg6,
1412                        USI pc)
1413 {
1414   CB_SYSCALL s;
1415   SIM_DESC sd = CPU_STATE (current_cpu);
1416   host_callback *cb = STATE_CALLBACK (sd);
1417   int retval;
1418   int threadno = current_cpu->threadno;
1419
1420   current_cpu->syscalls++;
1421
1422   CB_SYSCALL_INIT (&s);
1423   s.func = callnum;
1424   s.arg1 = arg1;
1425   s.arg2 = arg2;
1426   s.arg3 = arg3;
1427
1428   /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need
1429      to sign-extend the lseek offset to be passed as a signed number,
1430      else we'll truncate it to something > 2GB on hosts where sizeof
1431      long > sizeof USI.  We avoid doing it for all syscalls, as arg2 is
1432      e.g. an address for some syscalls.  */
1433   if (callnum == TARGET_SYS_lseek)
1434     s.arg2 = (SI) arg2;
1435
1436   if (callnum == TARGET_SYS_exit_group
1437       || (callnum == TARGET_SYS_exit && current_cpu->m1threads == 0))
1438     {
1439       if (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
1440           & FLAG_CRIS_MISC_PROFILE_ALL)
1441         dump_statistics (current_cpu);
1442       sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, arg1);
1443     }
1444
1445   s.p1 = sd;
1446   s.p2 = current_cpu;
1447   s.read_mem = sim_syscall_read_mem;
1448   s.write_mem = sim_syscall_write_mem;
1449
1450   current_cpu_for_cb_callback = current_cpu;
1451
1452   if (cb_syscall (cb, &s) != CB_RC_OK)
1453     {
1454       sim_engine_abort (sd, current_cpu, pc,
1455                         "Break 13: invalid %d?  Returned %ld\n", callnum,
1456                         s.result);
1457     }
1458
1459   retval = s.result == -1 ? -s.errcode : s.result;
1460
1461   if (s.errcode != 0 && s.errcode == cb_host_to_target_errno (cb, ENOSYS))
1462     {
1463       /* If the generic simulator call said ENOSYS, then let's try the
1464          ones we know ourselves.
1465
1466          The convention is to provide *very limited* functionality on an
1467          as-needed basis, only what's covered by the test-suite, tests
1468          added when functionality changes and abort with a descriptive
1469          message for *everything* else.  Where there's no test-case, we
1470          just abort.  */
1471       switch (callnum)
1472         {
1473         case 0:
1474           /* It's a pretty safe bet that the "old setup() system call"
1475              number will not be re-used; we can't say the same for higher
1476              numbers.  We treat this simulator-generated call as "wait
1477              forever"; we re-run this insn.  The wait is ended by a
1478              callback.  Sanity check that this is the reason we got
1479              here. */
1480           if (current_cpu->thread_data == NULL
1481               || (current_cpu->thread_data[threadno].pipe_write_fd == 0))
1482             goto unimplemented_syscall;
1483
1484           sim_pc_set (current_cpu, pc);
1485           retval = arg1;
1486           break;
1487
1488         case TARGET_SYS_fcntl64:
1489         case TARGET_SYS_fcntl:
1490           switch (arg2)
1491             {
1492             case 1:
1493               /* F_GETFD.
1494                  Glibc checks stdin, stdout and stderr fd:s for
1495                  close-on-exec security sanity.  We just need to provide a
1496                  OK return value.  If we really need to have a
1497                  close-on-exec flag true, we could just do a real fcntl
1498                  here.  */
1499               retval = 0;
1500               break;
1501
1502             case 2:
1503               /* F_SETFD.  Just ignore attempts to set the close-on-exec
1504                  flag.  */
1505               retval = 0;
1506               break;
1507
1508             case 3:
1509               /* F_GETFL.  Check for the special case for open+fdopen.  */
1510               if (current_cpu->last_syscall == TARGET_SYS_open
1511                   && arg1 == current_cpu->last_open_fd)
1512                 {
1513                   retval = current_cpu->last_open_flags & TARGET_O_ACCMODE;
1514                   break;
1515                 }
1516               else if (arg1 == 0)
1517                 {
1518                   /* Because we can't freopen fd:s 0, 1, 2 to mean
1519                      something else than stdin, stdout and stderr
1520                      (sim/common/syscall.c:cb_syscall special cases fd
1521                      0, 1 and 2), we know what flags that we can
1522                      sanely return for these fd:s.  */
1523                   retval = TARGET_O_RDONLY;
1524                   break;
1525                 }
1526               else if (arg1 == 1 || arg1 == 2)
1527                 {
1528                   retval = TARGET_O_WRONLY;
1529                   break;
1530                 }
1531               /* FALLTHROUGH */
1532             default:
1533               /* Nothing else is implemented.  */
1534               retval
1535                 = cris_unknown_syscall (current_cpu, pc,
1536                                         "Unimplemented %s syscall "
1537                                         "(fd: 0x%lx: cmd: 0x%lx arg: "
1538                                         "0x%lx)\n",
1539                                         callnum == TARGET_SYS_fcntl
1540                                         ? "fcntl" : "fcntl64",
1541                                         (unsigned long) (USI) arg1,
1542                                         (unsigned long) (USI) arg2,
1543                                         (unsigned long) (USI) arg3);
1544               break;
1545             }
1546           break;
1547
1548         case TARGET_SYS_uname:
1549           {
1550             /* Fill in a few constants to appease glibc.  */
1551             static char sim_utsname[6][65] =
1552             {
1553               "Linux",
1554               "sim-target",
1555               "2.6.27",
1556               TARGET_UTSNAME,
1557               "cris",           /* Overwritten below.  */
1558               "localdomain"
1559             };
1560
1561             /* Having the hardware type in Linux equal to the bfd
1562                printable name is deliberate: if you make config.guess
1563                work on your Linux-type system the usual way, it
1564                probably will; either the bfd printable_name or the
1565                ambiguous arch_name.  */
1566             strcpy (sim_utsname[4], STATE_ARCHITECTURE (sd)->printable_name);
1567
1568             if ((s.write_mem) (cb, &s, arg1, (const char *) sim_utsname,
1569                                sizeof (sim_utsname))
1570                 != sizeof (sim_utsname))
1571               retval = -cb_host_to_target_errno (cb, EFAULT);
1572             else
1573               retval = 0;
1574             break;
1575           }
1576
1577         case TARGET_SYS_geteuid32:
1578           /* We tell the truth with these.  Maybe we shouldn't, but it
1579              should match the "stat" information.  */
1580           retval = geteuid ();
1581           break;
1582
1583         case TARGET_SYS_getuid32:
1584           retval = getuid ();
1585           break;
1586
1587         case TARGET_SYS_getegid32:
1588           retval = getegid ();
1589           break;
1590
1591         case TARGET_SYS_getgid32:
1592           retval = getgid ();
1593           break;
1594
1595         case TARGET_SYS_brk:
1596           /* Most often, we just return the argument, like the Linux
1597              kernel.  */
1598           retval = arg1;
1599
1600           if (arg1 == 0)
1601             retval = current_cpu->endbrk;
1602           else if (arg1 <= current_cpu->endmem)
1603             current_cpu->endbrk = arg1;
1604           else
1605             {
1606               USI new_end = (arg1 + 8191) & ~8191;
1607
1608               /* If the simulator wants to brk more than a certain very
1609                  large amount, something is wrong.  FIXME: Return an error
1610                  or abort?  Have command-line selectable?  */
1611               if (new_end - current_cpu->endmem > SIM_MAX_ALLOC_CHUNK)
1612                 {
1613                   current_cpu->endbrk = current_cpu->endmem;
1614                   retval = current_cpu->endmem;
1615                   break;
1616                 }
1617
1618               sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
1619                                current_cpu->endmem,
1620                                new_end - current_cpu->endmem,
1621                                0, NULL, NULL);
1622               current_cpu->endbrk = arg1;
1623               current_cpu->endmem = new_end;
1624             }
1625           break;
1626
1627         case TARGET_SYS_getpid:
1628           /* Correct until CLONE_THREAD is implemented.  */
1629           retval = current_cpu->thread_data == NULL
1630             ? TARGET_PID
1631             : TARGET_PID + current_cpu->thread_data[threadno].threadid;
1632           break;
1633
1634         case TARGET_SYS_getppid:
1635           /* Correct until CLONE_THREAD is implemented.  */
1636           retval = current_cpu->thread_data == NULL
1637             ? TARGET_PID - 1
1638             : (TARGET_PID
1639                + current_cpu->thread_data[threadno].parent_threadid);
1640           break;
1641
1642         case TARGET_SYS_mmap2:
1643           {
1644             USI addr = arg1;
1645             USI len = arg2;
1646             USI prot = arg3;
1647             USI flags = arg4;
1648             USI fd = arg5;
1649             USI pgoff = arg6;
1650
1651             /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
1652                still masked away this bit, so let's just ignore
1653                it.  */
1654             flags &= ~TARGET_MAP_DENYWRITE;
1655
1656             /* If the simulator wants to mmap more than the very large
1657                limit, something is wrong.  FIXME: Return an error or
1658                abort?  Have command-line selectable?  */
1659             if (len > SIM_MAX_ALLOC_CHUNK)
1660               {
1661                 retval = -cb_host_to_target_errno (cb, ENOMEM);
1662                 break;
1663               }
1664
1665             if ((prot != (TARGET_PROT_READ | TARGET_PROT_WRITE)
1666                  && (prot
1667                      != (TARGET_PROT_READ
1668                          | TARGET_PROT_WRITE
1669                          | TARGET_PROT_EXEC))
1670                  && (prot != (TARGET_PROT_READ | TARGET_PROT_EXEC))
1671                  && prot != TARGET_PROT_READ)
1672                 || (flags != (TARGET_MAP_ANONYMOUS | TARGET_MAP_PRIVATE)
1673                     && flags != TARGET_MAP_PRIVATE
1674                     && flags != (TARGET_MAP_ANONYMOUS
1675                                  | TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
1676                     && flags != (TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
1677                     && flags != TARGET_MAP_SHARED)
1678                 || (fd != (USI) -1
1679                     && prot != TARGET_PROT_READ
1680                     && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
1681                     && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
1682                 || (fd == (USI) -1 && pgoff != 0)
1683                 || (fd != (USI) -1 && (flags & TARGET_MAP_ANONYMOUS)))
1684               {
1685                 retval
1686                   = cris_unknown_syscall (current_cpu, pc,
1687                                                  "Unimplemented mmap2 call "
1688                                                  "(0x%lx, 0x%lx, 0x%lx, "
1689                                                  "0x%lx, 0x%lx, 0x%lx)\n",
1690                                                  (unsigned long) arg1,
1691                                                  (unsigned long) arg2,
1692                                                  (unsigned long) arg3,
1693                                                  (unsigned long) arg4,
1694                                                  (unsigned long) arg5,
1695                                                  (unsigned long) arg6);
1696                 break;
1697               }
1698             else if (fd != (USI) -1)
1699               {
1700                 /* Map a file.  */
1701
1702                 USI newaddr;
1703                 USI pos;
1704
1705                 /* A non-aligned argument is allowed for files.  */
1706                 USI newlen = (len + 8191) & ~8191;
1707
1708                 /* We only support read, read|exec, and read|write,
1709                    which we should already have checked.  Check again
1710                    anyway.  */
1711                 if (prot != TARGET_PROT_READ
1712                     && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
1713                     && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
1714                   abort ();
1715
1716                 if (flags & TARGET_MAP_FIXED)
1717                   unmap_pages (sd, &current_cpu->highest_mmapped_page,
1718                                addr, newlen);
1719                 else if (is_mapped (sd, &current_cpu->highest_mmapped_page,
1720                                     addr, newlen))
1721                   addr = 0;
1722
1723                 newaddr
1724                   = create_map (sd, &current_cpu->highest_mmapped_page,
1725                                 addr != 0 || (flags & TARGET_MAP_FIXED)
1726                                 ? addr : -1,
1727                                 newlen);
1728
1729                 if (newaddr >= (USI) -8191)
1730                   {
1731                     abort ();
1732                     retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
1733                     break;
1734                   }
1735
1736                 /* We were asked for MAP_FIXED, but couldn't.  */
1737                 if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
1738                   {
1739                     abort ();
1740                     unmap_pages (sd, &current_cpu->highest_mmapped_page,
1741                                  newaddr, newlen);
1742                     retval = -cb_host_to_target_errno (cb, EINVAL);
1743                     break;
1744                   }
1745
1746                 /* Find the current position in the file.  */
1747                 s.func = TARGET_SYS_lseek;
1748                 s.arg1 = fd;
1749                 s.arg2 = 0;
1750                 s.arg3 = SEEK_CUR;
1751                 if (cb_syscall (cb, &s) != CB_RC_OK)
1752                   abort ();
1753                 pos = s.result;
1754
1755                 if (s.result < 0)
1756                   abort ();
1757
1758                 /* Move to the correct offset in the file.  */
1759                 s.func = TARGET_SYS_lseek;
1760                 s.arg1 = fd;
1761                 s.arg2 = pgoff*8192;
1762                 s.arg3 = SEEK_SET;
1763                 if (cb_syscall (cb, &s) != CB_RC_OK)
1764                   abort ();
1765
1766                 if (s.result < 0)
1767                   abort ();
1768
1769                 /* Use the standard read callback to read in "len"
1770                    bytes.  */
1771                 s.func = TARGET_SYS_read;
1772                 s.arg1 = fd;
1773                 s.arg2 = newaddr;
1774                 s.arg3 = len;
1775                 if (cb_syscall (cb, &s) != CB_RC_OK)
1776                   abort ();
1777
1778                 /* If the result is a page or more lesser than what
1779                    was requested, something went wrong.  */
1780                 if (len >= 8192 && (USI) s.result <= len - 8192)
1781                   abort ();
1782
1783                 /* After reading, we need to go back to the previous
1784                    position in the file.  */
1785                 s.func = TARGET_SYS_lseek;
1786                 s.arg1 = fd;
1787                 s.arg2 = pos;
1788                 s.arg3 = SEEK_SET;
1789                 if (cb_syscall (cb, &s) != CB_RC_OK)
1790                   abort ();
1791                 if (pos != (USI) s.result)
1792                   abort ();
1793
1794                 retval = newaddr;
1795               }
1796             else
1797               {
1798                 USI newlen = (len + 8191) & ~8191;
1799                 USI newaddr;
1800
1801                 if (flags & TARGET_MAP_FIXED)
1802                   unmap_pages (sd, &current_cpu->highest_mmapped_page,
1803                                addr, newlen);
1804                 else if (is_mapped (sd, &current_cpu->highest_mmapped_page,
1805                                     addr, newlen))
1806                   addr = 0;
1807
1808                 newaddr = create_map (sd, &current_cpu->highest_mmapped_page,
1809                                       addr != 0 || (flags & TARGET_MAP_FIXED)
1810                                       ? addr : -1,
1811                                       newlen);
1812
1813                 if (newaddr >= (USI) -8191)
1814                   retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
1815                 else
1816                   retval = newaddr;
1817
1818                 if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
1819                   {
1820                     abort ();
1821                     unmap_pages (sd, &current_cpu->highest_mmapped_page,
1822                                  newaddr, newlen);
1823                     retval = -cb_host_to_target_errno (cb, EINVAL);
1824                     break;
1825                   }
1826               }
1827             break;
1828           }
1829
1830         case TARGET_SYS_mprotect:
1831           {
1832             /* We only cover the case of linuxthreads mprotecting out
1833                its stack guard page and of dynamic loading mprotecting
1834                away the data (for some reason the whole library, then
1835                mprotects away the data part and mmap-FIX:es it again.  */
1836             USI addr = arg1;
1837             USI len = arg2;
1838             USI prot = arg3;
1839
1840             if (prot != TARGET_PROT_NONE
1841                 || !is_mapped_only (sd, &current_cpu->highest_mmapped_page,
1842                                     addr, (len + 8191) & ~8191))
1843               {
1844                 retval
1845                   = cris_unknown_syscall (current_cpu, pc,
1846                                           "Unimplemented mprotect call "
1847                                           "(0x%lx, 0x%lx, 0x%lx)\n",
1848                                           (unsigned long) arg1,
1849                                           (unsigned long) arg2,
1850                                           (unsigned long) arg3);
1851                 break;
1852               }
1853
1854             /* Just ignore this.  We could make this equal to munmap,
1855                but then we'd have to make sure no anon mmaps gets this
1856                address before a subsequent MAP_FIXED mmap intended to
1857                override it.  */
1858             retval = 0;
1859             break;
1860           }
1861
1862         case TARGET_SYS_ioctl:
1863           {
1864             /* We support only a very limited functionality: checking
1865                stdout with TCGETS to perform the isatty function.  The
1866                TCGETS ioctl isn't actually performed or the result used by
1867                an isatty () caller in a "hello, world" program; only the
1868                return value is then used.  Maybe we shouldn't care about
1869                the environment of the simulator regarding isatty, but
1870                that's been working before, in the xsim simulator.  */
1871             if (arg2 == TARGET_TCGETS && arg1 == 1)
1872               retval = isatty (1) ? 0 : cb_host_to_target_errno (cb, EINVAL);
1873             else
1874               retval = -cb_host_to_target_errno (cb, EINVAL);
1875             break;
1876           }
1877
1878         case TARGET_SYS_munmap:
1879           {
1880             USI addr = arg1;
1881             USI len = arg2;
1882             USI result
1883               = unmap_pages (sd, &current_cpu->highest_mmapped_page, addr,
1884                              len);
1885             retval = result != 0 ? -cb_host_to_target_errno (cb, result) : 0;
1886             break;
1887           }
1888
1889         case TARGET_SYS_wait4:
1890           {
1891             int i;
1892             USI pid = arg1;
1893             USI saddr = arg2;
1894             USI options = arg3;
1895             USI rusagep = arg4;
1896
1897             /* FIXME: We're not properly implementing __WCLONE, and we
1898                don't really need the special casing so we might as well
1899                make this general.  */
1900             if ((!(pid == (USI) -1
1901                    && options == (TARGET___WCLONE | TARGET_WNOHANG)
1902                    && saddr != 0)
1903                  && !(pid > 0
1904                       && (options == TARGET___WCLONE
1905                           || options == TARGET___WALL)))
1906                 || rusagep != 0
1907                 || current_cpu->thread_data == NULL)
1908               {
1909                 retval
1910                   = cris_unknown_syscall (current_cpu, pc,
1911                                           "Unimplemented wait4 call "
1912                                           "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
1913                                           (unsigned long) arg1,
1914                                           (unsigned long) arg2,
1915                                           (unsigned long) arg3,
1916                                           (unsigned long) arg4);
1917                 break;
1918               }
1919
1920             if (pid == (USI) -1)
1921               for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
1922                 {
1923                   if (current_cpu->thread_data[threadno].threadid
1924                       == current_cpu->thread_data[i].parent_threadid
1925                       && current_cpu->thread_data[i].threadid != 0
1926                       && current_cpu->thread_data[i].cpu_context == NULL)
1927                     {
1928                       /* A zombied child.  Get the exit value and clear the
1929                          zombied entry so it will be reused.  */
1930                       sim_core_write_unaligned_4 (current_cpu, pc, 0, saddr,
1931                                                   current_cpu
1932                                                   ->thread_data[i].exitval);
1933                       retval
1934                         = current_cpu->thread_data[i].threadid + TARGET_PID;
1935                       memset (&current_cpu->thread_data[i], 0,
1936                               sizeof (current_cpu->thread_data[i]));
1937                       goto outer_break;
1938                     }
1939                 }
1940             else
1941               {
1942                 /* We're waiting for a specific PID.  If we don't find
1943                    it zombied on this run, rerun the syscall.  */
1944                 for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
1945                   if (pid == current_cpu->thread_data[i].threadid + TARGET_PID
1946                       && current_cpu->thread_data[i].cpu_context == NULL)
1947                     {
1948                       if (saddr != 0)
1949                         /* Get the exit value if the caller wants it.  */
1950                         sim_core_write_unaligned_4 (current_cpu, pc, 0,
1951                                                     saddr,
1952                                                     current_cpu
1953                                                     ->thread_data[i]
1954                                                     .exitval);
1955
1956                       retval
1957                         = current_cpu->thread_data[i].threadid + TARGET_PID;
1958                       memset (&current_cpu->thread_data[i], 0,
1959                               sizeof (current_cpu->thread_data[i]));
1960
1961                       goto outer_break;
1962                     }
1963
1964                 sim_pc_set (current_cpu, pc);
1965               }
1966
1967             retval = -cb_host_to_target_errno (cb, ECHILD);
1968           outer_break:
1969             break;
1970           }
1971
1972         case TARGET_SYS_rt_sigaction:
1973           {
1974             USI signum = arg1;
1975             USI old_sa = arg3;
1976             USI new_sa = arg2;
1977
1978             /* The kernel says:
1979                struct sigaction {
1980                         __sighandler_t sa_handler;
1981                         unsigned long sa_flags;
1982                         void (*sa_restorer)(void);
1983                         sigset_t sa_mask;
1984                }; */
1985
1986             if (old_sa != 0)
1987               {
1988                 sim_core_write_unaligned_4 (current_cpu, pc, 0, old_sa + 0,
1989                                             current_cpu->sighandler[signum]);
1990                 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 4, 0);
1991                 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 8, 0);
1992
1993                 /* We'll assume _NSIG_WORDS is 2 for the kernel.  */
1994                 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 12, 0);
1995                 sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 16, 0);
1996               }
1997             if (new_sa != 0)
1998               {
1999                 USI target_sa_handler
2000                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa);
2001                 USI target_sa_flags
2002                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 4);
2003                 USI target_sa_restorer
2004                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 8);
2005                 USI target_sa_mask_low
2006                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 12);
2007                 USI target_sa_mask_high
2008                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 16);
2009
2010                 /* We won't interrupt a syscall so we won't restart it,
2011                    but a signal(2) call ends up syscalling rt_sigaction
2012                    with this flag, so we have to handle it.  The
2013                    sa_restorer field contains garbage when not
2014                    TARGET_SA_RESTORER, so don't look at it.  For the
2015                    time being, we don't nest sighandlers, so we
2016                    ignore the sa_mask, which simplifies things.  */
2017                 if ((target_sa_flags != 0
2018                      && target_sa_flags != TARGET_SA_RESTART
2019                      && target_sa_flags != (TARGET_SA_RESTART|TARGET_SA_SIGINFO))
2020                     || target_sa_handler == 0)
2021                   {
2022                     retval
2023                       = cris_unknown_syscall (current_cpu, pc,
2024                                               "Unimplemented rt_sigaction "
2025                                               "syscall "
2026                                               "(0x%lx, 0x%lx: "
2027                                               "[0x%x, 0x%x, 0x%x, "
2028                                               "{0x%x, 0x%x}], 0x%lx)\n",
2029                                               (unsigned long) arg1,
2030                                               (unsigned long) arg2,
2031                                               target_sa_handler,
2032                                               target_sa_flags,
2033                                               target_sa_restorer,
2034                                               target_sa_mask_low,
2035                                               target_sa_mask_high,
2036                                               (unsigned long) arg3);
2037                     break;
2038                   }
2039
2040                 current_cpu->sighandler[signum] = target_sa_handler;
2041
2042                 /* Because we may have unblocked signals, one may now be
2043                    pending, if there are threads, that is.  */
2044                 if (current_cpu->thread_data)
2045                   current_cpu->thread_data[threadno].sigpending = 1;
2046               }
2047             retval = 0;
2048             break;
2049           }
2050
2051         case TARGET_SYS_mremap:
2052           {
2053             USI addr = arg1;
2054             USI old_len = arg2;
2055             USI new_len = arg3;
2056             USI flags = arg4;
2057             USI new_addr = arg5;
2058             USI mapped_addr;
2059
2060             if (new_len == old_len)
2061               /* The program and/or library is possibly confused but
2062                  this is a valid call.  Happens with ipps-1.40 on file
2063                  svs_all.  */
2064               retval = addr;
2065             else if (new_len < old_len)
2066               {
2067                 /* Shrinking is easy.  */
2068                 if (unmap_pages (sd, &current_cpu->highest_mmapped_page,
2069                                  addr + new_len, old_len - new_len) != 0)
2070                   retval = -cb_host_to_target_errno (cb, EINVAL);
2071                 else
2072                   retval = addr;
2073               }
2074             else if (! is_mapped (sd, &current_cpu->highest_mmapped_page,
2075                                   addr + old_len, new_len - old_len))
2076               {
2077                 /* If the extension isn't mapped, we can just add it.  */
2078                 mapped_addr
2079                   = create_map (sd, &current_cpu->highest_mmapped_page,
2080                                 addr + old_len, new_len - old_len);
2081
2082                 if (mapped_addr > (USI) -8192)
2083                   retval = -cb_host_to_target_errno (cb, -(SI) mapped_addr);
2084                 else
2085                   retval = addr;
2086               }
2087             else if (flags & TARGET_MREMAP_MAYMOVE)
2088               {
2089                 /* Create a whole new map and copy the contents
2090                    block-by-block there.  We ignore the new_addr argument
2091                    for now.  */
2092                 char buf[8192];
2093                 USI prev_addr = addr;
2094                 USI prev_len = old_len;
2095
2096                 mapped_addr
2097                   = create_map (sd, &current_cpu->highest_mmapped_page,
2098                                 -1, new_len);
2099
2100                 if (mapped_addr > (USI) -8192)
2101                   {
2102                     retval = -cb_host_to_target_errno (cb, -(SI) new_addr);
2103                     break;
2104                   }
2105
2106                 retval = mapped_addr;
2107
2108                 for (; old_len > 0;
2109                      old_len -= 8192, mapped_addr += 8192, addr += 8192)
2110                   {
2111                     if (sim_core_read_buffer (sd, current_cpu, read_map, buf,
2112                                               addr, 8192) != 8192
2113                         || sim_core_write_buffer (sd, current_cpu, 0, buf,
2114                                                   mapped_addr, 8192) != 8192)
2115                       abort ();
2116                   }
2117
2118                 if (unmap_pages (sd, &current_cpu->highest_mmapped_page,
2119                                  prev_addr, prev_len) != 0)
2120                   abort ();
2121               }
2122             else
2123               retval = -cb_host_to_target_errno (cb, -ENOMEM);
2124             break;
2125           }
2126
2127         case TARGET_SYS_poll:
2128           {
2129             int npollfds = arg2;
2130             int timeout = arg3;
2131             SI ufds = arg1;
2132             SI fd = -1;
2133             HI events = -1;
2134             HI revents = 0;
2135             struct stat buf;
2136             int i;
2137
2138             /* The kernel says:
2139                 struct pollfd {
2140                      int fd;
2141                      short events;
2142                      short revents;
2143                 }; */
2144
2145             /* Check that this is the expected poll call from
2146                linuxthreads/manager.c; we don't support anything else.
2147                Remember, fd == 0 isn't supported.  */
2148             if (npollfds != 1
2149                 || ((fd = sim_core_read_unaligned_4 (current_cpu, pc,
2150                                                      0, ufds)) <= 0)
2151                 || ((events = sim_core_read_unaligned_2 (current_cpu, pc,
2152                                                          0, ufds + 4))
2153                     != TARGET_POLLIN)
2154                 || ((cb->to_fstat) (cb, fd, &buf) != 0
2155                     || (buf.st_mode & S_IFIFO) == 0)
2156                 || current_cpu->thread_data == NULL)
2157               {
2158                 retval
2159                   = cris_unknown_syscall (current_cpu, pc,
2160                                           "Unimplemented poll syscall "
2161                                           "(0x%lx: [0x%x, 0x%x, x], "
2162                                           "0x%lx, 0x%lx)\n",
2163                                           (unsigned long) arg1, fd, events,
2164                                           (unsigned long) arg2,
2165                                           (unsigned long) arg3);
2166                 break;
2167               }
2168
2169             retval = 0;
2170
2171             /* Iterate over threads; find a marker that a writer is
2172                sleeping, waiting for a reader.  */
2173             for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
2174               if (current_cpu->thread_data[i].cpu_context != NULL
2175                   && current_cpu->thread_data[i].pipe_read_fd == fd)
2176                 {
2177                   revents = TARGET_POLLIN;
2178                   retval = 1;
2179                   break;
2180                 }
2181
2182             /* Timeout decreases with whatever time passed between the
2183                last syscall and this.  That's not exactly right for the
2184                first call, but it's close enough that it isn't
2185                worthwhile to complicate matters by making that a special
2186                case.  */
2187             timeout
2188               -= (TARGET_TIME_MS (current_cpu)
2189                   - (current_cpu->thread_data[threadno].last_execution));
2190
2191             /* Arrange to repeat this syscall until timeout or event,
2192                decreasing timeout at each iteration.  */
2193             if (timeout > 0 && revents == 0)
2194               {
2195                 bfd_byte timeout_buf[4];
2196
2197                 bfd_putl32 (timeout, timeout_buf);
2198                 (*CPU_REG_STORE (current_cpu)) (current_cpu,
2199                                                 H_GR_R12, timeout_buf, 4);
2200                 sim_pc_set (current_cpu, pc);
2201                 retval = arg1;
2202                 break;
2203               }
2204
2205             sim_core_write_unaligned_2 (current_cpu, pc, 0, ufds + 4 + 2,
2206                                         revents);
2207             break;
2208           }
2209
2210         case TARGET_SYS_time:
2211           {
2212             retval = (int) (*cb->time) (cb);
2213
2214             /* At time of this writing, CB_SYSCALL_time doesn't do the
2215                part of setting *arg1 to the return value.  */
2216             if (arg1)
2217               sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, retval);
2218             break;
2219           }
2220
2221         case TARGET_SYS_gettimeofday:
2222           if (arg1 != 0)
2223             {
2224               USI ts = TARGET_TIME (current_cpu);
2225               USI tms = TARGET_TIME_MS (current_cpu);
2226
2227               /* First dword is seconds since TARGET_EPOCH.  */
2228               sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, ts);
2229
2230               /* Second dword is microseconds.  */
2231               sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1 + 4,
2232                                           (tms % 1000) * 1000);
2233             }
2234           if (arg2 != 0)
2235             {
2236               /* Time-zone info is always cleared.  */
2237               sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, 0);
2238               sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, 0);
2239             }
2240           retval = 0;
2241           break;
2242
2243         case TARGET_SYS_llseek:
2244           {
2245             /* If it fits, tweak parameters to fit the "generic" 32-bit
2246                lseek and use that.  */
2247             SI fd = arg1;
2248             SI offs_hi = arg2;
2249             SI offs_lo = arg3;
2250             SI resultp = arg4;
2251             SI whence = arg5;
2252             retval = 0;
2253
2254             if (!((offs_hi == 0 && offs_lo >= 0)
2255                   || (offs_hi == -1 &&  offs_lo < 0)))
2256               {
2257                 retval
2258                   = cris_unknown_syscall (current_cpu, pc,
2259                                           "Unimplemented llseek offset,"
2260                                           " fd %d: 0x%x:0x%x\n",
2261                                           fd, (unsigned) arg2,
2262                                           (unsigned) arg3);
2263                 break;
2264               }
2265
2266             s.func = TARGET_SYS_lseek;
2267             s.arg2 = offs_lo;
2268             s.arg3 = whence;
2269             if (cb_syscall (cb, &s) != CB_RC_OK)
2270               {
2271                 sim_io_eprintf (sd, "Break 13: invalid %d?  Returned %ld\n", callnum,
2272                                 s.result);
2273                 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
2274               }
2275             if (s.result < 0)
2276               retval = -s.errcode;
2277             else
2278               {
2279                 sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp,
2280                                             s.result);
2281                 sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp + 4,
2282                                             s.result < 0 ? -1 : 0);
2283               }
2284             break;
2285           }
2286
2287           /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
2288               where:
2289              struct iovec {
2290                void  *iov_base;    Starting address
2291                size_t iov_len;     Number of bytes to transfer
2292              }; */
2293         case TARGET_SYS_writev:
2294           {
2295             SI fd = arg1;
2296             SI iov = arg2;
2297             SI iovcnt = arg3;
2298             SI retcnt = 0;
2299             int i;
2300
2301             /* We'll ignore strict error-handling and just do multiple write calls.  */
2302             for (i = 0; i < iovcnt; i++)
2303               {
2304                 int sysret;
2305                 USI iov_base
2306                   = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2307                                                iov + 8*i);
2308                 USI iov_len
2309                   = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2310                                                iov + 8*i + 4);
2311                 
2312                 s.func = TARGET_SYS_write;
2313                 s.arg1 = fd;
2314                 s.arg2 = iov_base;
2315                 s.arg3 = iov_len;
2316
2317                 if (cb_syscall (cb, &s) != CB_RC_OK)
2318                   abort ();
2319                 sysret = s.result == -1 ? -s.errcode : s.result;
2320
2321                 if (sysret != iov_len)
2322                   {
2323                     if (i != 0)
2324                       abort ();
2325                     retcnt = sysret;
2326                     break;
2327                   }
2328
2329                 retcnt += iov_len;
2330               }
2331
2332             retval = retcnt;
2333           }
2334           break;
2335
2336         /* This one does have a generic callback function, but at the time
2337            of this writing, cb_syscall does not have code for it, and we
2338            need target-specific code for the threads implementation
2339            anyway.  */
2340         case TARGET_SYS_kill:
2341           {
2342             USI pid = arg1;
2343             USI sig = arg2;
2344
2345             retval = 0;
2346
2347             /* At kill(2), glibc sets signal masks such that the thread
2348                machinery is initialized.  Still, there is and was only
2349                one thread.  */
2350             if (current_cpu->max_threadid == 0)
2351               {
2352                 if (pid != TARGET_PID)
2353                   {
2354                     retval = -cb_host_to_target_errno (cb, EPERM);
2355                     break;
2356                   }
2357
2358                 /* FIXME: Signal infrastructure (target-to-sim mapping).  */
2359                 if (sig == TARGET_SIGABRT)
2360                   /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
2361                      the end-point for failing GCC test-cases.  */
2362                   sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2363                                    SIM_SIGABRT);
2364                 else
2365                   {
2366                     sim_io_eprintf (sd, "Unimplemented signal: %d\n", sig);
2367                     sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2368                                      SIM_SIGILL);
2369                   }
2370
2371                 /* This will not be reached.  */
2372                 abort ();
2373               }
2374             else
2375               retval = deliver_signal (current_cpu, sig, pid);
2376             break;
2377           }
2378
2379         case TARGET_SYS_rt_sigprocmask:
2380           {
2381             int i;
2382             USI how = arg1;
2383             USI newsetp = arg2;
2384             USI oldsetp = arg3;
2385
2386             if (how != TARGET_SIG_BLOCK
2387                 && how != TARGET_SIG_SETMASK
2388                 && how != TARGET_SIG_UNBLOCK)
2389               {
2390                 retval
2391                   = cris_unknown_syscall (current_cpu, pc,
2392                                           "Unimplemented rt_sigprocmask "
2393                                           "syscall (0x%x, 0x%x, 0x%x)\n",
2394                                           arg1, arg2, arg3);
2395                 break;
2396               }
2397
2398             if (newsetp)
2399               {
2400                 USI set_low
2401                   = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2402                                                newsetp);
2403                 USI set_high
2404                   = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2405                                                newsetp + 4);
2406
2407                 /* The sigmask is kept in the per-thread data, so we may
2408                    need to create the first one.  */
2409                 if (current_cpu->thread_data == NULL)
2410                   make_first_thread (current_cpu);
2411
2412                 if (how == TARGET_SIG_SETMASK)
2413                   for (i = 0; i < 64; i++)
2414                     current_cpu->thread_data[threadno].sigdata[i].blocked = 0;
2415
2416                 for (i = 0; i < 32; i++)
2417                   if ((set_low & (1 << i)))
2418                     current_cpu->thread_data[threadno].sigdata[i + 1].blocked
2419                       = (how != TARGET_SIG_UNBLOCK);
2420
2421                 for (i = 0; i < 31; i++)
2422                   if ((set_high & (1 << i)))
2423                     current_cpu->thread_data[threadno].sigdata[i + 33].blocked
2424                       = (how != TARGET_SIG_UNBLOCK);
2425
2426                 /* The mask changed, so a signal may be unblocked for
2427                    execution.  */
2428                 current_cpu->thread_data[threadno].sigpending = 1;
2429               }
2430
2431             if (oldsetp != 0)
2432               {
2433                 USI set_low = 0;
2434                 USI set_high = 0;
2435
2436                 for (i = 0; i < 32; i++)
2437                   if (current_cpu->thread_data[threadno]
2438                       .sigdata[i + 1].blocked)
2439                     set_low |= 1 << i;
2440                 for (i = 0; i < 31; i++)
2441                   if (current_cpu->thread_data[threadno]
2442                       .sigdata[i + 33].blocked)
2443                     set_high |= 1 << i;
2444
2445                 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 0, set_low);
2446                 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 4, set_high);
2447               }
2448
2449             retval = 0;
2450             break;
2451           }
2452
2453         case TARGET_SYS_sigreturn:
2454           {
2455             int i;
2456             bfd_byte regbuf[4];
2457             int was_sigsuspended;
2458
2459             if (current_cpu->thread_data == NULL
2460                 /* The CPU context is saved with the simulator data, not
2461                    on the stack as in the real world.  */
2462                 || (current_cpu->thread_data[threadno].cpu_context_atsignal
2463                     == NULL))
2464               {
2465                 retval
2466                   = cris_unknown_syscall (current_cpu, pc,
2467                                           "Invalid sigreturn syscall: "
2468                                           "no signal handler active "
2469                                           "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
2470                                           "0x%lx, 0x%lx)\n",
2471                                           (unsigned long) arg1,
2472                                           (unsigned long) arg2,
2473                                           (unsigned long) arg3,
2474                                           (unsigned long) arg4,
2475                                           (unsigned long) arg5,
2476                                           (unsigned long) arg6);
2477                 break;
2478               }
2479
2480             was_sigsuspended
2481               = current_cpu->thread_data[threadno].sigsuspended;
2482
2483             /* Restore the sigmask, either from the stack copy made when
2484                the sighandler was called, or from the saved state
2485                specifically for sigsuspend(2).  */
2486             if (was_sigsuspended)
2487               {
2488                 current_cpu->thread_data[threadno].sigsuspended = 0;
2489                 for (i = 0; i < 64; i++)
2490                   current_cpu->thread_data[threadno].sigdata[i].blocked
2491                     = current_cpu->thread_data[threadno]
2492                     .sigdata[i].blocked_suspendsave;
2493               }
2494             else
2495               {
2496                 USI sp;
2497                 USI set_low;
2498                 USI set_high;
2499
2500                 (*CPU_REG_FETCH (current_cpu)) (current_cpu,
2501                                             H_GR_SP, regbuf, 4);
2502                 sp = bfd_getl32 (regbuf);
2503                 set_low
2504                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp);
2505                 set_high
2506                   = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp + 4);
2507
2508                 for (i = 0; i < 32; i++)
2509                   current_cpu->thread_data[threadno].sigdata[i + 1].blocked
2510                     = (set_low & (1 << i)) != 0;
2511                 for (i = 0; i < 31; i++)
2512                   current_cpu->thread_data[threadno].sigdata[i + 33].blocked
2513                     = (set_high & (1 << i)) != 0;
2514               }
2515
2516             /* The mask changed, so a signal may be unblocked for
2517                execution.  */
2518             current_cpu->thread_data[threadno].sigpending = 1;
2519
2520             memcpy (&current_cpu->cpu_data_placeholder,
2521                     current_cpu->thread_data[threadno].cpu_context_atsignal,
2522                     current_cpu->thread_cpu_data_size);
2523             free (current_cpu->thread_data[threadno].cpu_context_atsignal);
2524             current_cpu->thread_data[threadno].cpu_context_atsignal = NULL;
2525
2526             /* The return value must come from the saved R10.  */
2527             (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, regbuf, 4);
2528             retval = bfd_getl32 (regbuf);
2529
2530             /* We must also break the "sigsuspension loop".  */
2531             if (was_sigsuspended)
2532               sim_pc_set (current_cpu, sim_pc_get (current_cpu) + 2);
2533             break;
2534           }
2535
2536         case TARGET_SYS_rt_sigsuspend:
2537           {
2538             USI newsetp = arg1;
2539             USI setsize = arg2;
2540
2541             if (setsize != 8)
2542               {
2543                 retval
2544                   = cris_unknown_syscall (current_cpu, pc,
2545                                           "Unimplemented rt_sigsuspend syscall"
2546                                           " arguments (0x%lx, 0x%lx)\n",
2547                                           (unsigned long) arg1,
2548                                           (unsigned long) arg2);
2549                 break;
2550               }
2551
2552             /* Don't change the signal mask if we're already in
2553                sigsuspend state (i.e. this syscall is a rerun).  */
2554             else if (!current_cpu->thread_data[threadno].sigsuspended)
2555               {
2556                 USI set_low
2557                   = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2558                                                newsetp);
2559                 USI set_high
2560                   = sim_core_read_unaligned_4 (current_cpu, pc, 0,
2561                                                newsetp + 4);
2562                 int i;
2563
2564                 /* Save the current sigmask and insert the user-supplied
2565                    one.  */
2566                 for (i = 0; i < 32; i++)
2567                   {
2568                     current_cpu->thread_data[threadno]
2569                       .sigdata[i + 1].blocked_suspendsave
2570                       = current_cpu->thread_data[threadno]
2571                       .sigdata[i + 1].blocked;
2572
2573                     current_cpu->thread_data[threadno]
2574                       .sigdata[i + 1].blocked = (set_low & (1 << i)) != 0;
2575                   }
2576                 for (i = 0; i < 31; i++)
2577                   {
2578                     current_cpu->thread_data[threadno]
2579                       .sigdata[i + 33].blocked_suspendsave
2580                       = current_cpu->thread_data[threadno]
2581                       .sigdata[i + 33].blocked;
2582                     current_cpu->thread_data[threadno]
2583                       .sigdata[i + 33].blocked = (set_high & (1 << i)) != 0;
2584                   }
2585
2586                 current_cpu->thread_data[threadno].sigsuspended = 1;
2587
2588                 /* The mask changed, so a signal may be unblocked for
2589                    execution. */
2590                 current_cpu->thread_data[threadno].sigpending = 1;
2591               }
2592
2593             /* Because we don't use arg1 (newsetp) when this syscall is
2594                rerun, it doesn't matter that we overwrite it with the
2595                (constant) return value.  */
2596             retval = -cb_host_to_target_errno (cb, EINTR);
2597             sim_pc_set (current_cpu, pc);
2598             break;
2599           }
2600
2601           /* Add case labels here for other syscalls using the 32-bit
2602              "struct stat", provided they have a corresponding simulator
2603              function of course.  */
2604         case TARGET_SYS_stat:
2605         case TARGET_SYS_fstat:
2606           {
2607             /* As long as the infrastructure doesn't cache anything
2608                related to the stat mapping, this trick gets us a dual
2609                "struct stat"-type mapping in the least error-prone way.  */
2610             const char *saved_map = cb->stat_map;
2611             CB_TARGET_DEFS_MAP *saved_syscall_map = cb->syscall_map;
2612
2613             cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_stat32_map;
2614             cb->stat_map = stat32_map;
2615
2616             if (cb_syscall (cb, &s) != CB_RC_OK)
2617               {
2618                 abort ();
2619                 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
2620                                  SIM_SIGILL);
2621               }
2622             retval = s.result == -1 ? -s.errcode : s.result;
2623
2624             cb->stat_map = saved_map;
2625             cb->syscall_map = saved_syscall_map;
2626             break;
2627           }
2628
2629         case TARGET_SYS_getcwd:
2630           {
2631             USI buf = arg1;
2632             USI size = arg2;
2633
2634             char *cwd = xmalloc (SIM_PATHMAX);
2635             if (cwd != getcwd (cwd, SIM_PATHMAX))
2636               abort ();
2637
2638             /* FIXME: When and if we support chdir, we need something
2639                a bit more elaborate.  */
2640             if (simulator_sysroot[0] != '\0')
2641               strcpy (cwd, "/");
2642
2643             retval = -cb_host_to_target_errno (cb, ERANGE);
2644             if (strlen (cwd) + 1 <= size)
2645               {
2646                 retval = strlen (cwd) + 1;
2647                 if (sim_core_write_buffer (sd, current_cpu, 0, cwd,
2648                                            buf, retval)
2649                     != (unsigned int) retval)
2650                   retval = -cb_host_to_target_errno (cb, EFAULT);
2651               }
2652             free (cwd);
2653             break;
2654           }
2655
2656         case TARGET_SYS_access:
2657           {
2658             SI path = arg1;
2659             SI mode = arg2;
2660             char *pbuf = xmalloc (SIM_PATHMAX);
2661             int i;
2662             int o = 0;
2663             int hmode = 0;
2664
2665             if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/')
2666               {
2667                 strcpy (pbuf, simulator_sysroot);
2668                 o += strlen (simulator_sysroot);
2669               }
2670
2671             for (i = 0; i + o < SIM_PATHMAX; i++)
2672               {
2673                 pbuf[i + o]
2674                   = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i);
2675                 if (pbuf[i + o] == 0)
2676                   break;
2677               }
2678
2679             if (i + o == SIM_PATHMAX)
2680               {
2681                 retval = -cb_host_to_target_errno (cb, ENAMETOOLONG);
2682                 break;
2683               }
2684
2685             /* Assert that we don't get calls for files for which we
2686                don't have support.  */
2687             if (strncmp (pbuf + strlen (simulator_sysroot),
2688                          "/proc/", 6) == 0)
2689               abort ();
2690 #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
2691             X_AFLAG (R_OK);
2692             X_AFLAG (W_OK);
2693             X_AFLAG (X_OK);
2694             X_AFLAG (F_OK);
2695 #undef X_AFLAG
2696
2697             if (access (pbuf, hmode) != 0)
2698               retval = -cb_host_to_target_errno (cb, errno);
2699             else
2700               retval = 0;
2701
2702             free (pbuf);
2703             break;
2704           }
2705
2706         case TARGET_SYS_readlink:
2707           {
2708             SI path = arg1;
2709             SI buf = arg2;
2710             SI bufsiz = arg3;
2711             char *pbuf = xmalloc (SIM_PATHMAX);
2712             char *lbuf = xmalloc (SIM_PATHMAX);
2713             char *lbuf_alloc = lbuf;
2714             int nchars = -1;
2715             int i;
2716             int o = 0;
2717
2718             if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/')
2719               {
2720                 strcpy (pbuf, simulator_sysroot);
2721                 o += strlen (simulator_sysroot);
2722               }
2723
2724             for (i = 0; i + o < SIM_PATHMAX; i++)
2725               {
2726                 pbuf[i + o]
2727                   = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i);
2728                 if (pbuf[i + o] == 0)
2729                   break;
2730               }
2731
2732             if (i + o == SIM_PATHMAX)
2733               {
2734                 retval = -cb_host_to_target_errno (cb, ENAMETOOLONG);
2735                 break;
2736               }
2737
2738             /* Intervene calls for certain files expected in the target
2739                proc file system.  */
2740             if (strcmp (pbuf + strlen (simulator_sysroot),
2741                         "/proc/" XSTRING (TARGET_PID) "/exe") == 0)
2742               {
2743                 char *argv0
2744                   = (STATE_PROG_ARGV (sd) != NULL
2745                      ? *STATE_PROG_ARGV (sd) : NULL);
2746
2747                 if (argv0 == NULL || *argv0 == '.')
2748                   {
2749                     retval
2750                       = cris_unknown_syscall (current_cpu, pc,
2751                                               "Unimplemented readlink syscall "
2752                                               "(0x%lx: [\"%s\"], 0x%lx)\n",
2753                                               (unsigned long) arg1, pbuf,
2754                                               (unsigned long) arg2);
2755                     break;
2756                   }
2757                 else if (*argv0 == '/')
2758                   {
2759                     if (strncmp (simulator_sysroot, argv0,
2760                                  strlen (simulator_sysroot)) == 0)
2761                       argv0 += strlen (simulator_sysroot);
2762
2763                     strcpy (lbuf, argv0);
2764                     nchars = strlen (argv0) + 1;
2765                   }
2766                 else
2767                   {
2768                     if (getcwd (lbuf, SIM_PATHMAX) != NULL
2769                         && strlen (lbuf) + 2 + strlen (argv0) < SIM_PATHMAX)
2770                       {
2771                         if (strncmp (simulator_sysroot, lbuf,
2772                                      strlen (simulator_sysroot)) == 0)
2773                           lbuf += strlen (simulator_sysroot);
2774
2775                         strcat (lbuf, "/");
2776                         strcat (lbuf, argv0);
2777                         nchars = strlen (lbuf) + 1;
2778                       }
2779                     else
2780                       abort ();
2781                   }
2782               }
2783             else
2784               nchars = readlink (pbuf, lbuf, SIM_PATHMAX);
2785
2786             /* We trust that the readlink result returns a *relative*
2787                link, or one already adjusted for the file-path-prefix.
2788                (We can't generally tell the difference, so we go with
2789                the easiest decision; no adjustment.)  */
2790
2791             if (nchars == -1)
2792               {
2793                 retval = -cb_host_to_target_errno (cb, errno);
2794                 break;
2795               }
2796
2797             if (bufsiz < nchars)
2798               nchars = bufsiz;
2799
2800             if (sim_core_write_buffer (sd, current_cpu, write_map, lbuf,
2801                                        buf, nchars) != (unsigned int) nchars)
2802               retval = -cb_host_to_target_errno (cb, EFAULT);
2803             else
2804               retval = nchars;
2805
2806             free (pbuf);
2807             free (lbuf_alloc);
2808             break;
2809           }
2810
2811         case TARGET_SYS_sched_getscheduler:
2812           {
2813             USI pid = arg1;
2814
2815             /* FIXME: Search (other) existing threads.  */
2816             if (pid != 0 && pid != TARGET_PID)
2817               retval = -cb_host_to_target_errno (cb, ESRCH);
2818             else
2819               retval = TARGET_SCHED_OTHER;
2820             break;
2821           }
2822
2823         case TARGET_SYS_sched_getparam:
2824           {
2825             USI pid = arg1;
2826             USI paramp = arg2;
2827
2828             /* The kernel says:
2829                struct sched_param {
2830                         int sched_priority;
2831                }; */
2832
2833             if (pid != 0 && pid != TARGET_PID)
2834               retval = -cb_host_to_target_errno (cb, ESRCH);
2835             else
2836               {
2837                 /* FIXME: Save scheduler setting before threads are
2838                    created too.  */
2839                 sim_core_write_unaligned_4 (current_cpu, pc, 0, paramp,
2840                                             current_cpu->thread_data != NULL
2841                                             ? (current_cpu
2842                                                ->thread_data[threadno]
2843                                                .priority)
2844                                             : 0);
2845                 retval = 0;
2846               }
2847             break;
2848           }
2849
2850         case TARGET_SYS_sched_setparam:
2851           {
2852             USI pid = arg1;
2853             USI paramp = arg2;
2854
2855             if ((pid != 0 && pid != TARGET_PID)
2856                 || sim_core_read_unaligned_4 (current_cpu, pc, 0,
2857                                               paramp) != 0)
2858               retval = -cb_host_to_target_errno (cb, EINVAL);
2859             else
2860               retval = 0;
2861             break;
2862           }
2863
2864         case TARGET_SYS_sched_setscheduler:
2865           {
2866             USI pid = arg1;
2867             USI policy = arg2;
2868             USI paramp = arg3;
2869
2870             if ((pid != 0 && pid != TARGET_PID)
2871                 || policy != TARGET_SCHED_OTHER
2872                 || sim_core_read_unaligned_4 (current_cpu, pc, 0,
2873                                               paramp) != 0)
2874               retval = -cb_host_to_target_errno (cb, EINVAL);
2875             else
2876               /* FIXME: Save scheduler setting to be read in later
2877                  sched_getparam calls.  */
2878               retval = 0;
2879             break;
2880           }
2881
2882         case TARGET_SYS_sched_yield:
2883           /* We reschedule to the next thread after a syscall anyway, so
2884              we don't have to do anything here than to set the return
2885              value.  */
2886           retval = 0;
2887           break;
2888
2889         case TARGET_SYS_sched_get_priority_min:
2890         case TARGET_SYS_sched_get_priority_max:
2891           if (arg1 != 0)
2892             retval = -cb_host_to_target_errno (cb, EINVAL);
2893           else
2894             retval = 0;
2895           break;
2896
2897         case TARGET_SYS_ugetrlimit:
2898           {
2899             unsigned int curlim, maxlim;
2900             if (arg1 != TARGET_RLIMIT_STACK && arg1 != TARGET_RLIMIT_NOFILE)
2901               {
2902                 retval = -cb_host_to_target_errno (cb, EINVAL);
2903                 break;
2904               }
2905
2906             /* The kernel says:
2907                struct rlimit {
2908                        unsigned long   rlim_cur;
2909                        unsigned long   rlim_max;
2910                }; */
2911             if (arg1 == TARGET_RLIMIT_NOFILE)
2912               {
2913                 /* Sadly a very low limit.  Better not lie, though.  */
2914                 maxlim = curlim = MAX_CALLBACK_FDS;
2915               }
2916             else /* arg1 == TARGET_RLIMIT_STACK */
2917               {
2918                 maxlim = 0xffffffff;
2919                 curlim = 0x800000;
2920               }
2921             sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, curlim);
2922             sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, maxlim);
2923             retval = 0;
2924             break;
2925           }
2926
2927         case TARGET_SYS_setrlimit:
2928           if (arg1 != TARGET_RLIMIT_STACK)
2929             {
2930               retval = -cb_host_to_target_errno (cb, EINVAL);
2931               break;
2932             }
2933           /* FIXME: Save values for future ugetrlimit calls.  */
2934           retval = 0;
2935           break;
2936
2937         /* Provide a very limited subset of the sysctl functions, and
2938            abort for the rest. */
2939         case TARGET_SYS__sysctl:
2940           {
2941             /* The kernel says:
2942                struct __sysctl_args {
2943                 int *name;
2944                 int nlen;
2945                 void *oldval;
2946                 size_t *oldlenp;
2947                 void *newval;
2948                 size_t newlen;
2949                 unsigned long __unused[4];
2950                }; */
2951             SI name = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1);
2952             SI name0 = name == 0
2953               ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name);
2954             SI name1 = name == 0
2955               ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name + 4);
2956             SI nlen
2957               =  sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 4);
2958             SI oldval
2959               =  sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 8);
2960             SI oldlenp
2961               =  sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 12);
2962             SI oldlen = oldlenp == 0
2963               ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, oldlenp);
2964             SI newval
2965               =  sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 16);
2966             SI newlen
2967               = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 20);
2968
2969             if (name0 == TARGET_CTL_KERN && name1 == TARGET_CTL_KERN_VERSION)
2970               {
2971                 SI to_write = oldlen < (SI) sizeof (TARGET_UTSNAME)
2972                   ? oldlen : (SI) sizeof (TARGET_UTSNAME);
2973
2974                 sim_core_write_unaligned_4 (current_cpu, pc, 0, oldlenp,
2975                                             sizeof (TARGET_UTSNAME));
2976
2977                 if (sim_core_write_buffer (sd, current_cpu, write_map,
2978                                            TARGET_UTSNAME, oldval,
2979                                            to_write)
2980                     != (unsigned int) to_write)
2981                   retval = -cb_host_to_target_errno (cb, EFAULT);
2982                 else
2983                   retval = 0;
2984                 break;
2985               }
2986
2987             retval
2988               = cris_unknown_syscall (current_cpu, pc,
2989                                       "Unimplemented _sysctl syscall "
2990                                       "(0x%lx: [0x%lx, 0x%lx],"
2991                                       " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
2992                                       (unsigned long) name,
2993                                       (unsigned long) name0,
2994                                       (unsigned long) name1,
2995                                       (unsigned long) nlen,
2996                                       (unsigned long) oldval,
2997                                       (unsigned long) oldlenp,
2998                                       (unsigned long) newval,
2999                                       (unsigned long) newlen);
3000             break;
3001           }
3002
3003         case TARGET_SYS_exit:
3004           {
3005             /* Here for all but the last thread.  */
3006             int i;
3007             int pid
3008               = current_cpu->thread_data[threadno].threadid + TARGET_PID;
3009             int ppid
3010               = (current_cpu->thread_data[threadno].parent_threadid
3011                  + TARGET_PID);
3012             int exitsig = current_cpu->thread_data[threadno].exitsig;
3013
3014             /* Any children are now all orphans.  */
3015             for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
3016               if (current_cpu->thread_data[i].parent_threadid
3017                   == current_cpu->thread_data[threadno].threadid)
3018                 /* Make getppid(2) return 1 for them, poor little ones.  */
3019                 current_cpu->thread_data[i].parent_threadid = -TARGET_PID + 1;
3020
3021             /* Free the cpu context data.  When the parent has received
3022                the exit status, we'll clear the entry too.  */
3023             free (current_cpu->thread_data[threadno].cpu_context);
3024             current_cpu->thread_data[threadno].cpu_context = NULL;
3025             current_cpu->m1threads--;
3026             if (arg1 != 0)
3027               {
3028                 sim_io_eprintf (sd, "Thread %d exited with status %d\n",
3029                                 pid, arg1);
3030                 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
3031                                  SIM_SIGILL);
3032               }
3033
3034             /* Still, we may want to support non-zero exit values.  */
3035             current_cpu->thread_data[threadno].exitval = arg1 << 8;
3036
3037             if (exitsig)
3038               deliver_signal (current_cpu, exitsig, ppid);
3039             break;
3040           }
3041
3042         case TARGET_SYS_clone:
3043           {
3044             int nthreads = current_cpu->m1threads + 1;
3045             void *thread_cpu_data;
3046             bfd_byte old_sp_buf[4];
3047             bfd_byte sp_buf[4];
3048             const bfd_byte zeros[4] = { 0, 0, 0, 0 };
3049             int i;
3050
3051             /* That's right, the syscall clone arguments are reversed
3052                compared to sys_clone notes in clone(2) and compared to
3053                other Linux ports (i.e. it's the same order as in the
3054                clone(2) libcall).  */
3055             USI flags = arg2;
3056             USI newsp = arg1;
3057
3058             if (nthreads == SIM_TARGET_MAX_THREADS)
3059               {
3060                 retval = -cb_host_to_target_errno (cb, EAGAIN);
3061                 break;
3062               }
3063
3064             /* FIXME: Implement the low byte.  */
3065             if ((flags & ~TARGET_CSIGNAL) !=
3066                 (TARGET_CLONE_VM
3067                  | TARGET_CLONE_FS
3068                  | TARGET_CLONE_FILES
3069                  | TARGET_CLONE_SIGHAND)
3070                 || newsp == 0)
3071               {
3072                 retval
3073                   = cris_unknown_syscall (current_cpu, pc,
3074                                           "Unimplemented clone syscall "
3075                                           "(0x%lx, 0x%lx)\n",
3076                                           (unsigned long) arg1,
3077                                           (unsigned long) arg2);
3078                 break;
3079               }
3080
3081             if (current_cpu->thread_data == NULL)
3082               make_first_thread (current_cpu);
3083
3084             /* The created thread will get the new SP and a cleared R10.
3085                Since it's created out of a copy of the old thread and we
3086                don't have a set-register-function that just take the
3087                cpu_data as a parameter, we set the childs values first,
3088                and write back or overwrite them in the parent after the
3089                copy.  */
3090             (*CPU_REG_FETCH (current_cpu)) (current_cpu,
3091                                             H_GR_SP, old_sp_buf, 4);
3092             bfd_putl32 (newsp, sp_buf);
3093             (*CPU_REG_STORE (current_cpu)) (current_cpu,
3094                                             H_GR_SP, sp_buf, 4);
3095             (*CPU_REG_STORE (current_cpu)) (current_cpu,
3096                                             H_GR_R10, (bfd_byte *) zeros, 4);
3097             thread_cpu_data
3098               = (*current_cpu
3099                  ->make_thread_cpu_data) (current_cpu,
3100                                           &current_cpu->cpu_data_placeholder);
3101             (*CPU_REG_STORE (current_cpu)) (current_cpu,
3102                                             H_GR_SP, old_sp_buf, 4);
3103
3104             retval = ++current_cpu->max_threadid + TARGET_PID;
3105
3106             /* Find an unused slot.  After a few threads have been created
3107                and exited, the array is expected to be a bit fragmented.
3108                We don't reuse the first entry, though, that of the
3109                original thread.  */
3110             for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
3111               if (current_cpu->thread_data[i].cpu_context == NULL
3112                   /* Don't reuse a zombied entry.  */
3113                   && current_cpu->thread_data[i].threadid == 0)
3114                 break;
3115
3116             memcpy (&current_cpu->thread_data[i],
3117                     &current_cpu->thread_data[threadno],
3118                     sizeof (current_cpu->thread_data[i]));
3119             current_cpu->thread_data[i].cpu_context = thread_cpu_data;
3120             current_cpu->thread_data[i].cpu_context_atsignal = NULL;
3121             current_cpu->thread_data[i].threadid = current_cpu->max_threadid;
3122             current_cpu->thread_data[i].parent_threadid
3123               = current_cpu->thread_data[threadno].threadid;
3124             current_cpu->thread_data[i].pipe_read_fd = 0;
3125             current_cpu->thread_data[i].pipe_write_fd = 0;
3126             current_cpu->thread_data[i].at_syscall = 0;
3127             current_cpu->thread_data[i].sigpending = 0;
3128             current_cpu->thread_data[i].sigsuspended = 0;
3129             current_cpu->thread_data[i].exitsig = flags & TARGET_CSIGNAL;
3130             current_cpu->m1threads = nthreads;
3131             break;
3132           }
3133
3134         /* Better watch these in case they do something necessary.  */
3135         case TARGET_SYS_socketcall:
3136           retval = -cb_host_to_target_errno (cb, ENOSYS);
3137           break;
3138
3139         case TARGET_SYS_set_thread_area:
3140           /* Do the same error check as Linux.  */
3141           if (arg1 & 255)
3142             {
3143               retval = -cb_host_to_target_errno (cb, EINVAL);
3144               break;
3145             }
3146           (*current_cpu->set_target_thread_data) (current_cpu, arg1);
3147           retval = 0;
3148           break;
3149
3150         unimplemented_syscall:
3151         default:
3152           retval
3153             = cris_unknown_syscall (current_cpu, pc,
3154                                     "Unimplemented syscall: %d "
3155                                     "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
3156                                     callnum, arg1, arg2, arg3, arg4, arg5,
3157                                     arg6);
3158         }
3159     }
3160
3161   /* Minimal support for fcntl F_GETFL as used in open+fdopen.  */
3162   if (callnum == TARGET_SYS_open)
3163     {
3164       current_cpu->last_open_fd = retval;
3165       current_cpu->last_open_flags = arg2;
3166     }
3167
3168   current_cpu->last_syscall = callnum;
3169
3170   /* A system call is a rescheduling point.  For the time being, we don't
3171      reschedule anywhere else.  */
3172   if (current_cpu->m1threads != 0
3173       /* We need to schedule off from an exiting thread that is the
3174          second-last one.  */
3175       || (current_cpu->thread_data != NULL
3176           && current_cpu->thread_data[threadno].cpu_context == NULL))
3177     {
3178       bfd_byte retval_buf[4];
3179
3180       current_cpu->thread_data[threadno].last_execution
3181         = TARGET_TIME_MS (current_cpu);
3182       bfd_putl32 (retval, retval_buf);
3183       (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
3184
3185       current_cpu->thread_data[threadno].at_syscall = 1;
3186       reschedule (current_cpu);
3187
3188       (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
3189       retval = bfd_getl32 (retval_buf);
3190     }
3191
3192   return retval;
3193 }
3194
3195 /* Callback from simulator write saying that the pipe at (reader, writer)
3196    is now non-empty (so the writer should wait until the pipe is empty, at
3197    least not write to this or any other pipe).  Simplest is to just wait
3198    until the pipe is empty.  */
3199
3200 static void
3201 cris_pipe_nonempty (host_callback *cb ATTRIBUTE_UNUSED,
3202                     int reader, int writer)
3203 {
3204   SIM_CPU *cpu = current_cpu_for_cb_callback;
3205   const bfd_byte zeros[4] = { 0, 0, 0, 0 };
3206
3207   /* It's the current thread: we just have to re-run the current
3208      syscall instruction (presumably "break 13") and change the syscall
3209      to the special simulator-wait code.  Oh, and set a marker that
3210      we're waiting, so we can disambiguate the special call from a
3211      program error.
3212
3213      This function may be called multiple times between cris_pipe_empty,
3214      but we must avoid e.g. decreasing PC every time.  Check fd markers
3215      to tell.  */
3216   if (cpu->thread_data == NULL)
3217     {
3218       sim_io_eprintf (CPU_STATE (cpu),
3219                       "Terminating simulation due to writing pipe rd:wr %d:%d"
3220                       " from one single thread\n", reader, writer);
3221       sim_engine_halt (CPU_STATE (cpu), cpu,
3222                        NULL, sim_pc_get (cpu), sim_stopped, SIM_SIGILL);
3223     }
3224   else if (cpu->thread_data[cpu->threadno].pipe_write_fd == 0)
3225     {
3226       cpu->thread_data[cpu->threadno].pipe_write_fd = writer;
3227       cpu->thread_data[cpu->threadno].pipe_read_fd = reader;
3228       /* FIXME: We really shouldn't change registers other than R10 in
3229          syscalls (like R9), here or elsewhere.  */
3230       (*CPU_REG_STORE (cpu)) (cpu, H_GR_R9, (bfd_byte *) zeros, 4);
3231       sim_pc_set (cpu, sim_pc_get (cpu) - 2);
3232     }
3233 }
3234
3235 /* Callback from simulator close or read call saying that the pipe at
3236    (reader, writer) is now empty (so the writer can write again, perhaps
3237    leave a waiting state).  If there are bytes remaining, they couldn't be
3238    consumed (perhaps due to the pipe closing).  */
3239
3240 static void
3241 cris_pipe_empty (host_callback *cb,
3242                  int reader,
3243                  int writer)
3244 {
3245   int i;
3246   SIM_CPU *cpu = current_cpu_for_cb_callback;
3247   SIM_DESC sd = CPU_STATE (current_cpu_for_cb_callback);
3248   bfd_byte r10_buf[4];
3249   int remaining
3250     = cb->pipe_buffer[writer].size - cb->pipe_buffer[reader].size;
3251
3252   /* We need to find the thread that waits for this pipe.  */
3253   for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
3254     if (cpu->thread_data[i].cpu_context
3255         && cpu->thread_data[i].pipe_write_fd == writer)
3256       {
3257         int retval;
3258
3259         /* Temporarily switch to this cpu context, so we can change the
3260            PC by ordinary calls.  */
3261
3262         memcpy (cpu->thread_data[cpu->threadno].cpu_context,
3263                 &cpu->cpu_data_placeholder,
3264                 cpu->thread_cpu_data_size);
3265         memcpy (&cpu->cpu_data_placeholder,
3266                 cpu->thread_data[i].cpu_context,
3267                 cpu->thread_cpu_data_size);
3268
3269         /* The return value is supposed to contain the number of
3270            written bytes, which is the number of bytes requested and
3271            returned at the write call.  You might think the right
3272            thing is to adjust the return-value to be only the
3273            *consumed* number of bytes, but it isn't.  We're only
3274            called if the pipe buffer is fully consumed or it is being
3275            closed, possibly with remaining bytes.  For the latter
3276            case, the writer is still supposed to see success for
3277            PIPE_BUF bytes (a constant which we happen to know and is
3278            unlikely to change).  The return value may also be a
3279            negative number; an error value.  This case is covered
3280            because "remaining" is always >= 0.  */
3281         (*CPU_REG_FETCH (cpu)) (cpu, H_GR_R10, r10_buf, 4);
3282         retval = (int) bfd_getl_signed_32 (r10_buf);
3283         if (retval - remaining > TARGET_PIPE_BUF)
3284           {
3285             bfd_putl32 (retval - remaining, r10_buf);
3286             (*CPU_REG_STORE (cpu)) (cpu, H_GR_R10, r10_buf, 4);
3287           }
3288         sim_pc_set (cpu, sim_pc_get (cpu) + 2);
3289         memcpy (cpu->thread_data[i].cpu_context,
3290                 &cpu->cpu_data_placeholder,
3291                 cpu->thread_cpu_data_size);
3292         memcpy (&cpu->cpu_data_placeholder,
3293                 cpu->thread_data[cpu->threadno].cpu_context,
3294                 cpu->thread_cpu_data_size);
3295         cpu->thread_data[i].pipe_read_fd = 0;
3296         cpu->thread_data[i].pipe_write_fd = 0;
3297         return;
3298       }
3299
3300   abort ();
3301 }
3302
3303 /* We have a simulator-specific notion of time.  See TARGET_TIME.  */
3304
3305 static int64_t
3306 cris_time (host_callback *cb ATTRIBUTE_UNUSED)
3307 {
3308   return TARGET_TIME (current_cpu_for_cb_callback);
3309 }
3310
3311 static int
3312 cris_getpid (host_callback *cb ATTRIBUTE_UNUSED)
3313 {
3314   return TARGET_PID;
3315 }
3316
3317 /* Set target-specific callback data. */
3318
3319 void
3320 cris_set_callbacks (host_callback *cb)
3321 {
3322   /* Yeargh, have to cast away constness to avoid warnings.  */
3323   cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_map;
3324   cb->errno_map = (CB_TARGET_DEFS_MAP *) errno_map;
3325
3326   cb->getpid = cris_getpid;
3327
3328   /* The kernel stat64 layout.  If we see a file > 2G, the "long"
3329      parameter to cb_store_target_endian will make st_size negative.
3330      Similarly for st_ino.  FIXME: Find a 64-bit type, and use it
3331      *unsigned*, and/or add syntax for signed-ness.  */
3332   cb->stat_map = stat_map;
3333   cb->open_map = (CB_TARGET_DEFS_MAP *) open_map;
3334   cb->pipe_nonempty = cris_pipe_nonempty;
3335   cb->pipe_empty = cris_pipe_empty;
3336   cb->time = cris_time;
3337 }
3338
3339 /* Process an address exception.  */
3340
3341 void
3342 cris_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
3343                   unsigned int map, int nr_bytes, address_word addr,
3344                   transfer_type transfer, sim_core_signals sig)
3345 {
3346   sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
3347                    transfer, sig);
3348 }
This page took 0.210961 seconds and 4 git commands to generate.