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