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