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