/* CRIS exception, interrupt, and trap (EIT) support
- Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2004-2021 Free Software Foundation, Inc.
Contributed by Axis Communications.
This file is part of the GNU simulators.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "sim-main.h"
+#include "sim-syscall.h"
#include "sim-options.h"
#include "bfd.h"
/* FIXME: get rid of targ-vals.h usage everywhere else. */
+#include <stdlib.h>
#include <stdarg.h>
-#ifdef HAVE_ERRNO_H
#include <errno.h>
-#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#define TARGET_SYS_time 13
#define TARGET_SYS_lseek 19
#define TARGET_SYS_getpid 20
+#define TARGET_SYS_access 33
#define TARGET_SYS_kill 37
#define TARGET_SYS_rename 38
#define TARGET_SYS_pipe 42
#define TARGET_SYS_getegid32 202
#define TARGET_SYS_getgid32 200
#define TARGET_SYS_fcntl64 221
+#define TARGET_SYS_set_thread_area 243
+#define TARGET_SYS_exit_group 252
#define TARGET_PROT_READ 0x1
#define TARGET_PROT_WRITE 0x2
#define TARGET_MAP_TYPE 0x0f
#define TARGET_MAP_FIXED 0x10
#define TARGET_MAP_ANONYMOUS 0x20
+#define TARGET_MAP_DENYWRITE 0x800
#define TARGET_CTL_KERN 1
#define TARGET_CTL_VM 2
#define TARGET_TCGETS 0x5401
-#define TARGET_UTSNAME "#38 Sun Apr 1 00:00:00 MET 2001"
+#define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
-/* Seconds since the above date + 10 minutes. */
-#define TARGET_EPOCH 986080200
+/* Seconds since 1970-01-01 to the above date + 10 minutes;
+ 'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'. */
+#define TARGET_EPOCH 1230764410
/* Milliseconds since start of run. We use the number of syscalls to
avoid introducing noise in the execution time. */
/* From linux/limits.h. */
#define TARGET_PIPE_BUF 4096
+/* From unistd.h. */
+#define TARGET_R_OK 4
+#define TARGET_W_OK 2
+#define TARGET_X_OK 1
+#define TARGET_F_OK 0
+
static const char stat_map[] =
"st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
static const CB_TARGET_DEFS_MAP syscall_map[] =
{
- { CB_SYS_open, TARGET_SYS_open },
- { CB_SYS_close, TARGET_SYS_close },
- { CB_SYS_read, TARGET_SYS_read },
- { CB_SYS_write, TARGET_SYS_write },
- { CB_SYS_lseek, TARGET_SYS_lseek },
- { CB_SYS_unlink, TARGET_SYS_unlink },
- { CB_SYS_getpid, TARGET_SYS_getpid },
- { CB_SYS_fstat, TARGET_SYS_fstat64 },
- { CB_SYS_lstat, TARGET_SYS_lstat64 },
- { CB_SYS_stat, TARGET_SYS_stat64 },
- { CB_SYS_pipe, TARGET_SYS_pipe },
- { CB_SYS_rename, TARGET_SYS_rename },
- { CB_SYS_truncate, TARGET_SYS_truncate },
- { CB_SYS_ftruncate, TARGET_SYS_ftruncate },
- { 0, -1 }
+ { "open", CB_SYS_open, TARGET_SYS_open },
+ { "close", CB_SYS_close, TARGET_SYS_close },
+ { "read", CB_SYS_read, TARGET_SYS_read },
+ { "write", CB_SYS_write, TARGET_SYS_write },
+ { "lseek", CB_SYS_lseek, TARGET_SYS_lseek },
+ { "unlink", CB_SYS_unlink, TARGET_SYS_unlink },
+ { "getpid", CB_SYS_getpid, TARGET_SYS_getpid },
+ { "fstat", CB_SYS_fstat, TARGET_SYS_fstat64 },
+ { "lstat", CB_SYS_lstat, TARGET_SYS_lstat64 },
+ { "stat", CB_SYS_stat, TARGET_SYS_stat64 },
+ { "pipe", CB_SYS_pipe, TARGET_SYS_pipe },
+ { "rename", CB_SYS_rename, TARGET_SYS_rename },
+ { "truncate", CB_SYS_truncate, TARGET_SYS_truncate },
+ { "ftruncate", CB_SYS_ftruncate, TARGET_SYS_ftruncate },
+ { 0, -1, -1 }
};
/* An older, 32-bit-only stat mapping. */
newlib Linux mapping. */
static const CB_TARGET_DEFS_MAP syscall_stat32_map[] =
{
- { CB_SYS_fstat, TARGET_SYS_fstat },
- { CB_SYS_stat, TARGET_SYS_stat },
- { 0, -1 }
+ { "fstat", CB_SYS_fstat, TARGET_SYS_fstat },
+ { "stat", CB_SYS_stat, TARGET_SYS_stat },
+ { 0, -1, -1 }
};
/* Giving the true value for the running sim process will lead to
static const CB_TARGET_DEFS_MAP errno_map[] =
{
#ifdef EPERM
- { EPERM, 1 },
+ { "EPERM", EPERM, 1 },
#endif
#ifdef ENOENT
- { ENOENT, 2 },
+ { "ENOENT", ENOENT, 2 },
#endif
#ifdef ESRCH
- { ESRCH, 3 },
+ { "ESRCH", ESRCH, 3 },
#endif
#ifdef EINTR
- { EINTR, 4 },
+ { "EINTR", EINTR, 4 },
#endif
#ifdef EIO
- { EIO, 5 },
+ { "EIO", EIO, 5 },
#endif
#ifdef ENXIO
- { ENXIO, 6 },
+ { "ENXIO", ENXIO, 6 },
#endif
#ifdef E2BIG
- { E2BIG, 7 },
+ { "E2BIG", E2BIG, 7 },
#endif
#ifdef ENOEXEC
- { ENOEXEC, 8 },
+ { "ENOEXEC", ENOEXEC, 8 },
#endif
#ifdef EBADF
- { EBADF, 9 },
+ { "EBADF", EBADF, 9 },
#endif
#ifdef ECHILD
- { ECHILD, 10 },
+ { "ECHILD", ECHILD, 10 },
#endif
#ifdef EAGAIN
- { EAGAIN, 11 },
+ { "EAGAIN", EAGAIN, 11 },
#endif
#ifdef ENOMEM
- { ENOMEM, 12 },
+ { "ENOMEM", ENOMEM, 12 },
#endif
#ifdef EACCES
- { EACCES, 13 },
+ { "EACCES", EACCES, 13 },
#endif
#ifdef EFAULT
- { EFAULT, 14 },
+ { "EFAULT", EFAULT, 14 },
#endif
#ifdef ENOTBLK
- { ENOTBLK, 15 },
+ { "ENOTBLK", ENOTBLK, 15 },
#endif
#ifdef EBUSY
- { EBUSY, 16 },
+ { "EBUSY", EBUSY, 16 },
#endif
#ifdef EEXIST
- { EEXIST, 17 },
+ { "EEXIST", EEXIST, 17 },
#endif
#ifdef EXDEV
- { EXDEV, 18 },
+ { "EXDEV", EXDEV, 18 },
#endif
#ifdef ENODEV
- { ENODEV, 19 },
+ { "ENODEV", ENODEV, 19 },
#endif
#ifdef ENOTDIR
- { ENOTDIR, 20 },
+ { "ENOTDIR", ENOTDIR, 20 },
#endif
#ifdef EISDIR
- { EISDIR, 21 },
+ { "EISDIR", EISDIR, 21 },
#endif
#ifdef EINVAL
- { EINVAL, 22 },
+ { "EINVAL", EINVAL, 22 },
#endif
#ifdef ENFILE
- { ENFILE, 23 },
+ { "ENFILE", ENFILE, 23 },
#endif
#ifdef EMFILE
- { EMFILE, 24 },
+ { "EMFILE", EMFILE, 24 },
#endif
#ifdef ENOTTY
- { ENOTTY, 25 },
+ { "ENOTTY", ENOTTY, 25 },
#endif
#ifdef ETXTBSY
- { ETXTBSY, 26 },
+ { "ETXTBSY", ETXTBSY, 26 },
#endif
#ifdef EFBIG
- { EFBIG, 27 },
+ { "EFBIG", EFBIG, 27 },
#endif
#ifdef ENOSPC
- { ENOSPC, 28 },
+ { "ENOSPC", ENOSPC, 28 },
#endif
#ifdef ESPIPE
- { ESPIPE, 29 },
+ { "ESPIPE", ESPIPE, 29 },
#endif
#ifdef EROFS
- { EROFS, 30 },
+ { "EROFS", EROFS, 30 },
#endif
#ifdef EMLINK
- { EMLINK, 31 },
+ { "EMLINK", EMLINK, 31 },
#endif
#ifdef EPIPE
- { EPIPE, 32 },
+ { "EPIPE", EPIPE, 32 },
#endif
#ifdef EDOM
- { EDOM, 33 },
+ { "EDOM", EDOM, 33 },
#endif
#ifdef ERANGE
- { ERANGE, 34 },
+ { "ERANGE", ERANGE, 34 },
#endif
#ifdef EDEADLK
- { EDEADLK, 35 },
+ { "EDEADLK", EDEADLK, 35 },
#endif
#ifdef ENAMETOOLONG
- { ENAMETOOLONG, 36 },
+ { "ENAMETOOLONG", ENAMETOOLONG, 36 },
#endif
#ifdef ENOLCK
- { ENOLCK, 37 },
+ { "ENOLCK", ENOLCK, 37 },
#endif
#ifdef ENOSYS
- { ENOSYS, 38 },
+ { "ENOSYS", ENOSYS, 38 },
#endif
#ifdef ENOTEMPTY
- { ENOTEMPTY, 39 },
+ { "ENOTEMPTY", ENOTEMPTY, 39 },
#endif
#ifdef ELOOP
- { ELOOP, 40 },
+ { "ELOOP", ELOOP, 40 },
#endif
#ifdef EWOULDBLOCK
- { EWOULDBLOCK, 11 },
+ { "EWOULDBLOCK", EWOULDBLOCK, 11 },
#endif
#ifdef ENOMSG
- { ENOMSG, 42 },
+ { "ENOMSG", ENOMSG, 42 },
#endif
#ifdef EIDRM
- { EIDRM, 43 },
+ { "EIDRM", EIDRM, 43 },
#endif
#ifdef ECHRNG
- { ECHRNG, 44 },
+ { "ECHRNG", ECHRNG, 44 },
#endif
#ifdef EL2NSYNC
- { EL2NSYNC, 45 },
+ { "EL2NSYNC", EL2NSYNC, 45 },
#endif
#ifdef EL3HLT
- { EL3HLT, 46 },
+ { "EL3HLT", EL3HLT, 46 },
#endif
#ifdef EL3RST
- { EL3RST, 47 },
+ { "EL3RST", EL3RST, 47 },
#endif
#ifdef ELNRNG
- { ELNRNG, 48 },
+ { "ELNRNG", ELNRNG, 48 },
#endif
#ifdef EUNATCH
- { EUNATCH, 49 },
+ { "EUNATCH", EUNATCH, 49 },
#endif
#ifdef ENOCSI
- { ENOCSI, 50 },
+ { "ENOCSI", ENOCSI, 50 },
#endif
#ifdef EL2HLT
- { EL2HLT, 51 },
+ { "EL2HLT", EL2HLT, 51 },
#endif
#ifdef EBADE
- { EBADE, 52 },
+ { "EBADE", EBADE, 52 },
#endif
#ifdef EBADR
- { EBADR, 53 },
+ { "EBADR", EBADR, 53 },
#endif
#ifdef EXFULL
- { EXFULL, 54 },
+ { "EXFULL", EXFULL, 54 },
#endif
#ifdef ENOANO
- { ENOANO, 55 },
+ { "ENOANO", ENOANO, 55 },
#endif
#ifdef EBADRQC
- { EBADRQC, 56 },
+ { "EBADRQC", EBADRQC, 56 },
#endif
#ifdef EBADSLT
- { EBADSLT, 57 },
+ { "EBADSLT", EBADSLT, 57 },
#endif
#ifdef EDEADLOCK
- { EDEADLOCK, 35 },
+ { "EDEADLOCK", EDEADLOCK, 35 },
#endif
#ifdef EBFONT
- { EBFONT, 59 },
+ { "EBFONT", EBFONT, 59 },
#endif
#ifdef ENOSTR
- { ENOSTR, 60 },
+ { "ENOSTR", ENOSTR, 60 },
#endif
#ifdef ENODATA
- { ENODATA, 61 },
+ { "ENODATA", ENODATA, 61 },
#endif
#ifdef ETIME
- { ETIME, 62 },
+ { "ETIME", ETIME, 62 },
#endif
#ifdef ENOSR
- { ENOSR, 63 },
+ { "ENOSR", ENOSR, 63 },
#endif
#ifdef ENONET
- { ENONET, 64 },
+ { "ENONET", ENONET, 64 },
#endif
#ifdef ENOPKG
- { ENOPKG, 65 },
+ { "ENOPKG", ENOPKG, 65 },
#endif
#ifdef EREMOTE
- { EREMOTE, 66 },
+ { "EREMOTE", EREMOTE, 66 },
#endif
#ifdef ENOLINK
- { ENOLINK, 67 },
+ { "ENOLINK", ENOLINK, 67 },
#endif
#ifdef EADV
- { EADV, 68 },
+ { "EADV", EADV, 68 },
#endif
#ifdef ESRMNT
- { ESRMNT, 69 },
+ { "ESRMNT", ESRMNT, 69 },
#endif
#ifdef ECOMM
- { ECOMM, 70 },
+ { "ECOMM", ECOMM, 70 },
#endif
#ifdef EPROTO
- { EPROTO, 71 },
+ { "EPROTO", EPROTO, 71 },
#endif
#ifdef EMULTIHOP
- { EMULTIHOP, 72 },
+ { "EMULTIHOP", EMULTIHOP, 72 },
#endif
#ifdef EDOTDOT
- { EDOTDOT, 73 },
+ { "EDOTDOT", EDOTDOT, 73 },
#endif
#ifdef EBADMSG
- { EBADMSG, 74 },
+ { "EBADMSG", EBADMSG, 74 },
#endif
#ifdef EOVERFLOW
- { EOVERFLOW, 75 },
+ { "EOVERFLOW", EOVERFLOW, 75 },
#endif
#ifdef ENOTUNIQ
- { ENOTUNIQ, 76 },
+ { "ENOTUNIQ", ENOTUNIQ, 76 },
#endif
#ifdef EBADFD
- { EBADFD, 77 },
+ { "EBADFD", EBADFD, 77 },
#endif
#ifdef EREMCHG
- { EREMCHG, 78 },
+ { "EREMCHG", EREMCHG, 78 },
#endif
#ifdef ELIBACC
- { ELIBACC, 79 },
+ { "ELIBACC", ELIBACC, 79 },
#endif
#ifdef ELIBBAD
- { ELIBBAD, 80 },
+ { "ELIBBAD", ELIBBAD, 80 },
#endif
#ifdef ELIBSCN
- { ELIBSCN, 81 },
+ { "ELIBSCN", ELIBSCN, 81 },
#endif
#ifdef ELIBMAX
- { ELIBMAX, 82 },
+ { "ELIBMAX", ELIBMAX, 82 },
#endif
#ifdef ELIBEXEC
- { ELIBEXEC, 83 },
+ { "ELIBEXEC", ELIBEXEC, 83 },
#endif
#ifdef EILSEQ
- { EILSEQ, 84 },
+ { "EILSEQ", EILSEQ, 84 },
#endif
#ifdef ERESTART
- { ERESTART, 85 },
+ { "ERESTART", ERESTART, 85 },
#endif
#ifdef ESTRPIPE
- { ESTRPIPE, 86 },
+ { "ESTRPIPE", ESTRPIPE, 86 },
#endif
#ifdef EUSERS
- { EUSERS, 87 },
+ { "EUSERS", EUSERS, 87 },
#endif
#ifdef ENOTSOCK
- { ENOTSOCK, 88 },
+ { "ENOTSOCK", ENOTSOCK, 88 },
#endif
#ifdef EDESTADDRREQ
- { EDESTADDRREQ, 89 },
+ { "EDESTADDRREQ", EDESTADDRREQ, 89 },
#endif
#ifdef EMSGSIZE
- { EMSGSIZE, 90 },
+ { "EMSGSIZE", EMSGSIZE, 90 },
#endif
#ifdef EPROTOTYPE
- { EPROTOTYPE, 91 },
+ { "EPROTOTYPE", EPROTOTYPE, 91 },
#endif
#ifdef ENOPROTOOPT
- { ENOPROTOOPT, 92 },
+ { "ENOPROTOOPT", ENOPROTOOPT, 92 },
#endif
#ifdef EPROTONOSUPPORT
- { EPROTONOSUPPORT, 93 },
+ { "EPROTONOSUPPORT", EPROTONOSUPPORT, 93 },
#endif
#ifdef ESOCKTNOSUPPORT
- { ESOCKTNOSUPPORT, 94 },
+ { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, 94 },
#endif
#ifdef EOPNOTSUPP
- { EOPNOTSUPP, 95 },
+ { "EOPNOTSUPP", EOPNOTSUPP, 95 },
#endif
#ifdef EPFNOSUPPORT
- { EPFNOSUPPORT, 96 },
+ { "EPFNOSUPPORT", EPFNOSUPPORT, 96 },
#endif
#ifdef EAFNOSUPPORT
- { EAFNOSUPPORT, 97 },
+ { "EAFNOSUPPORT", EAFNOSUPPORT, 97 },
#endif
#ifdef EADDRINUSE
- { EADDRINUSE, 98 },
+ { "EADDRINUSE", EADDRINUSE, 98 },
#endif
#ifdef EADDRNOTAVAIL
- { EADDRNOTAVAIL, 99 },
+ { "EADDRNOTAVAIL", EADDRNOTAVAIL, 99 },
#endif
#ifdef ENETDOWN
- { ENETDOWN, 100 },
+ { "ENETDOWN", ENETDOWN, 100 },
#endif
#ifdef ENETUNREACH
- { ENETUNREACH, 101 },
+ { "ENETUNREACH", ENETUNREACH, 101 },
#endif
#ifdef ENETRESET
- { ENETRESET, 102 },
+ { "ENETRESET", ENETRESET, 102 },
#endif
#ifdef ECONNABORTED
- { ECONNABORTED, 103 },
+ { "ECONNABORTED", ECONNABORTED, 103 },
#endif
#ifdef ECONNRESET
- { ECONNRESET, 104 },
+ { "ECONNRESET", ECONNRESET, 104 },
#endif
#ifdef ENOBUFS
- { ENOBUFS, 105 },
+ { "ENOBUFS", ENOBUFS, 105 },
#endif
#ifdef EISCONN
- { EISCONN, 106 },
+ { "EISCONN", EISCONN, 106 },
#endif
#ifdef ENOTCONN
- { ENOTCONN, 107 },
+ { "ENOTCONN", ENOTCONN, 107 },
#endif
#ifdef ESHUTDOWN
- { ESHUTDOWN, 108 },
+ { "ESHUTDOWN", ESHUTDOWN, 108 },
#endif
#ifdef ETOOMANYREFS
- { ETOOMANYREFS, 109 },
+ { "ETOOMANYREFS", ETOOMANYREFS, 109 },
#endif
#ifdef ETIMEDOUT
- { ETIMEDOUT, 110 },
+ { "ETIMEDOUT", ETIMEDOUT, 110 },
#endif
#ifdef ECONNREFUSED
- { ECONNREFUSED, 111 },
+ { "ECONNREFUSED", ECONNREFUSED, 111 },
#endif
#ifdef EHOSTDOWN
- { EHOSTDOWN, 112 },
+ { "EHOSTDOWN", EHOSTDOWN, 112 },
#endif
#ifdef EHOSTUNREACH
- { EHOSTUNREACH, 113 },
+ { "EHOSTUNREACH", EHOSTUNREACH, 113 },
#endif
#ifdef EALREADY
- { EALREADY, 114 },
+ { "EALREADY", EALREADY, 114 },
#endif
#ifdef EINPROGRESS
- { EINPROGRESS, 115 },
+ { "EINPROGRESS", EINPROGRESS, 115 },
#endif
#ifdef ESTALE
- { ESTALE, 116 },
+ { "ESTALE", ESTALE, 116 },
#endif
#ifdef EUCLEAN
- { EUCLEAN, 117 },
+ { "EUCLEAN", EUCLEAN, 117 },
#endif
#ifdef ENOTNAM
- { ENOTNAM, 118 },
+ { "ENOTNAM", ENOTNAM, 118 },
#endif
#ifdef ENAVAIL
- { ENAVAIL, 119 },
+ { "ENAVAIL", ENAVAIL, 119 },
#endif
#ifdef EISNAM
- { EISNAM, 120 },
+ { "EISNAM", EISNAM, 120 },
#endif
#ifdef EREMOTEIO
- { EREMOTEIO, 121 },
+ { "EREMOTEIO", EREMOTEIO, 121 },
#endif
#ifdef EDQUOT
- { EDQUOT, 122 },
+ { "EDQUOT", EDQUOT, 122 },
#endif
#ifdef ENOMEDIUM
- { ENOMEDIUM, 123 },
+ { "ENOMEDIUM", ENOMEDIUM, 123 },
#endif
#ifdef EMEDIUMTYPE
- { EMEDIUMTYPE, 124 },
+ { "EMEDIUMTYPE", EMEDIUMTYPE, 124 },
#endif
- { 0, -1 }
+ { 0, 0, 0 }
};
/* Extracted by applying
static const CB_TARGET_DEFS_MAP open_map[] = {
#ifdef O_ACCMODE
- { O_ACCMODE, TARGET_O_ACCMODE },
+ { "O_ACCMODE", O_ACCMODE, TARGET_O_ACCMODE },
#endif
#ifdef O_RDONLY
- { O_RDONLY, TARGET_O_RDONLY },
+ { "O_RDONLY", O_RDONLY, TARGET_O_RDONLY },
#endif
#ifdef O_WRONLY
- { O_WRONLY, TARGET_O_WRONLY },
+ { "O_WRONLY", O_WRONLY, TARGET_O_WRONLY },
#endif
#ifdef O_RDWR
- { O_RDWR, 0x2 },
+ { "O_RDWR", O_RDWR, 0x2 },
#endif
#ifdef O_CREAT
- { O_CREAT, 0x40 },
+ { "O_CREAT", O_CREAT, 0x40 },
#endif
#ifdef O_EXCL
- { O_EXCL, 0x80 },
+ { "O_EXCL", O_EXCL, 0x80 },
#endif
#ifdef O_NOCTTY
- { O_NOCTTY, 0x100 },
+ { "O_NOCTTY", O_NOCTTY, 0x100 },
#endif
#ifdef O_TRUNC
- { O_TRUNC, 0x200 },
+ { "O_TRUNC", O_TRUNC, 0x200 },
#endif
#ifdef O_APPEND
- { O_APPEND, 0x400 },
+ { "O_APPEND", O_APPEND, 0x400 },
#endif
#ifdef O_NONBLOCK
- { O_NONBLOCK, 0x800 },
+ { "O_NONBLOCK", O_NONBLOCK, 0x800 },
#endif
#ifdef O_NDELAY
- { O_NDELAY, 0x0 },
+ { "O_NDELAY", O_NDELAY, 0x0 },
#endif
#ifdef O_SYNC
- { O_SYNC, 0x1000 },
+ { "O_SYNC", O_SYNC, 0x1000 },
#endif
#ifdef FASYNC
- { FASYNC, 0x2000 },
+ { "FASYNC", FASYNC, 0x2000 },
#endif
#ifdef O_DIRECT
- { O_DIRECT, 0x4000 },
+ { "O_DIRECT", O_DIRECT, 0x4000 },
#endif
#ifdef O_LARGEFILE
- { O_LARGEFILE, 0x8000 },
+ { "O_LARGEFILE", O_LARGEFILE, 0x8000 },
#endif
#ifdef O_DIRECTORY
- { O_DIRECTORY, 0x10000 },
+ { "O_DIRECTORY", O_DIRECTORY, 0x10000 },
#endif
#ifdef O_NOFOLLOW
- { O_NOFOLLOW, 0x20000 },
+ { "O_NOFOLLOW", O_NOFOLLOW, 0x20000 },
#endif
- { -1, -1 }
+ { 0, -1, -1 }
};
+/* Let's be less drastic and more traceable. FIXME: mark as noreturn. */
+#define abort() \
+ sim_io_error (sd, "simulator unhandled condition at %s:%d", \
+ __FUNCTION__, __LINE__)
+
/* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
static SIM_CPU *current_cpu_for_cb_callback;
-static int syscall_read_mem (host_callback *, struct cb_syscall *,
- unsigned long, char *, int);
-static int syscall_write_mem (host_callback *, struct cb_syscall *,
- unsigned long, const char *, int);
static USI create_map (SIM_DESC, struct cris_sim_mmapped_page **,
USI addr, USI len);
static USI unmap_pages (SIM_DESC, struct cris_sim_mmapped_page **,
static void dump_statistics (SIM_CPU *current_cpu);
static void make_first_thread (SIM_CPU *current_cpu);
-/* Read/write functions for system call interface. */
-
-static int
-syscall_read_mem (host_callback *cb ATTRIBUTE_UNUSED,
- struct cb_syscall *sc,
- unsigned long taddr, char *buf, int bytes)
-{
- SIM_DESC sd = (SIM_DESC) sc->p1;
- SIM_CPU *cpu = (SIM_CPU *) sc->p2;
-
- return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
-}
-
-static int
-syscall_write_mem (host_callback *cb ATTRIBUTE_UNUSED,
- struct cb_syscall *sc,
- unsigned long taddr, const char *buf, int bytes)
-{
- SIM_DESC sd = (SIM_DESC) sc->p1;
- SIM_CPU *cpu = (SIM_CPU *) sc->p2;
-
- return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
-}
-
/* When we risk running self-modified code (as in trampolines), this is
called from special-case insns. The silicon CRIS CPU:s have enough
cache snooping implemented making this a simulator-only issue. Tests:
sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
}
-/* Create mmapped memory. */
+/* Create mmapped memory. ADDR is -1 if any address will do. Caller
+ must make sure that the address isn't already mapped. */
static USI
create_map (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
struct cris_sim_mmapped_page **higher_prevp = rootp;
USI new_addr = 0x40000000;
- if (addr != 0)
+ if (addr != (USI) -1)
new_addr = addr;
- else if (*rootp)
+ else if (*rootp && rootp[0]->addr >= new_addr)
new_addr = rootp[0]->addr + 8192;
if (len != 8192)
mapp = mapp->prev)
higher_prevp = &mapp->prev;
+ /* Assert for consistency that we don't create duplicate maps. */
+ if (is_mapped (sd, rootp, new_addr, len))
+ abort ();
+
/* Allocate the new page, on the next higher page from the last one
allocated, and link in the new descriptor before previous ones. */
mapp = malloc (sizeof (*mapp));
if (len != 8192)
{
USI page_addr;
+ int ret = 0;
if (len & 8191)
/* Which is better: return an error for this, or just round it up? */
/* Loop backwards to make each call is O(1) over the number of pages
allocated, if we're unmapping from the high end of the pages. */
for (page_addr = addr + len - 8192;
- page_addr >= addr;
+ page_addr > addr;
page_addr -= 8192)
- if (unmap_pages (sd, rootp, page_addr, 8192) != 0)
- abort ();
+ if (unmap_pages (sd, rootp, page_addr, 8192))
+ ret = EINVAL;
+
+ if (unmap_pages (sd, rootp, addr, 8192))
+ ret = EINVAL;
- return 0;
+ return ret;
}
for (mapp = *rootp; mapp != NULL && mapp->addr > addr; mapp = mapp->prev)
UINT srcreg ATTRIBUTE_UNUSED,
USI dstreg ATTRIBUTE_UNUSED)
{
+ SIM_DESC sd = CPU_STATE (current_cpu);
abort ();
}
USI page ATTRIBUTE_UNUSED,
USI newval ATTRIBUTE_UNUSED)
{
+ SIM_DESC sd = CPU_STATE (current_cpu);
abort ();
}
UINT index ATTRIBUTE_UNUSED,
USI page ATTRIBUTE_UNUSED)
{
+ SIM_DESC sd = CPU_STATE (current_cpu);
abort ();
}
static void
reschedule (SIM_CPU *current_cpu)
{
+ SIM_DESC sd = CPU_STATE (current_cpu);
int i;
/* Iterate over all thread slots, because after a few thread creations
static void
make_first_thread (SIM_CPU *current_cpu)
{
+ SIM_DESC sd = CPU_STATE (current_cpu);
current_cpu->thread_data
= xcalloc (1,
SIM_TARGET_MAX_THREADS
s.arg2 = arg2;
s.arg3 = arg3;
- if (callnum == TARGET_SYS_exit && current_cpu->m1threads == 0)
+ /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need
+ to sign-extend the lseek offset to be passed as a signed number,
+ else we'll truncate it to something > 2GB on hosts where sizeof
+ long > sizeof USI. We avoid doing it for all syscalls, as arg2 is
+ e.g. an address for some syscalls. */
+ if (callnum == TARGET_SYS_lseek)
+ s.arg2 = (SI) arg2;
+
+ if (callnum == TARGET_SYS_exit_group
+ || (callnum == TARGET_SYS_exit && current_cpu->m1threads == 0))
{
if (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
& FLAG_CRIS_MISC_PROFILE_ALL)
s.p1 = (PTR) sd;
s.p2 = (PTR) current_cpu;
- s.read_mem = syscall_read_mem;
- s.write_mem = syscall_write_mem;
+ s.read_mem = sim_syscall_read_mem;
+ s.write_mem = sim_syscall_write_mem;
current_cpu_for_cb_callback = current_cpu;
case TARGET_SYS_uname:
{
/* Fill in a few constants to appease glibc. */
- static const char sim_utsname[6][65] =
+ static char sim_utsname[6][65] =
{
"Linux",
"sim-target",
- "2.4.5",
+ "2.6.27",
TARGET_UTSNAME,
- "cris",
+ "cris", /* Overwritten below. */
"localdomain"
};
+ /* Having the hardware type in Linux equal to the bfd
+ printable name is deliberate: if you make config.guess
+ work on your Linux-type system the usual way, it
+ probably will; either the bfd printable_name or the
+ ambiguous arch_name. */
+ strcpy (sim_utsname[4], STATE_ARCHITECTURE (sd)->printable_name);
+
if ((s.write_mem) (cb, &s, arg1, (const char *) sim_utsname,
sizeof (sim_utsname))
!= sizeof (sim_utsname))
USI fd = arg5;
USI pgoff = arg6;
+ /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
+ still masked away this bit, so let's just ignore
+ it. */
+ flags &= ~TARGET_MAP_DENYWRITE;
+
/* If the simulator wants to mmap more than the very large
limit, something is wrong. FIXME: Return an error or
abort? Have command-line selectable? */
&& prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
&& prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
|| (fd == (USI) -1 && pgoff != 0)
- || (fd != (USI) -1 && (flags & TARGET_MAP_ANONYMOUS))
- || ((flags & TARGET_MAP_FIXED) == 0
- && is_mapped (sd, ¤t_cpu->highest_mmapped_page,
- addr, (len + 8191) & ~8191)))
+ || (fd != (USI) -1 && (flags & TARGET_MAP_ANONYMOUS)))
{
retval
= cris_unknown_syscall (current_cpu, pc,
&& prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
abort ();
- if ((flags & TARGET_MAP_FIXED)
- && unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
- addr, newlen) != 0)
- abort ();
+ if (flags & TARGET_MAP_FIXED)
+ unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
+ addr, newlen);
+ else if (is_mapped (sd, ¤t_cpu->highest_mmapped_page,
+ addr, newlen))
+ addr = 0;
newaddr
- = create_map (sd, ¤t_cpu->highest_mmapped_page, addr,
+ = create_map (sd, ¤t_cpu->highest_mmapped_page,
+ addr != 0 || (flags & TARGET_MAP_FIXED)
+ ? addr : -1,
newlen);
if (newaddr >= (USI) -8191)
if (cb_syscall (cb, &s) != CB_RC_OK)
abort ();
- if ((USI) s.result != len)
+ /* If the result is a page or more lesser than what
+ was requested, something went wrong. */
+ if (len >= 8192 && (USI) s.result <= len - 8192)
abort ();
/* After reading, we need to go back to the previous
USI newlen = (len + 8191) & ~8191;
USI newaddr;
- if ((flags & TARGET_MAP_FIXED)
- && unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
- addr, newlen) != 0)
- abort ();
+ if (flags & TARGET_MAP_FIXED)
+ unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
+ addr, newlen);
+ else if (is_mapped (sd, ¤t_cpu->highest_mmapped_page,
+ addr, newlen))
+ addr = 0;
- newaddr = create_map (sd, ¤t_cpu->highest_mmapped_page, addr,
- newlen);
+ newaddr = create_map (sd, ¤t_cpu->highest_mmapped_page,
+ addr != 0 || (flags & TARGET_MAP_FIXED)
+ ? addr : -1,
+ newlen);
if (newaddr >= (USI) -8191)
retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
mapped_addr
= create_map (sd, ¤t_cpu->highest_mmapped_page,
- 0, new_len);
+ -1, new_len);
if (mapped_addr > (USI) -8192)
{
|| ((events = sim_core_read_unaligned_2 (current_cpu, pc,
0, ufds + 4))
!= TARGET_POLLIN)
- || ((cb->fstat) (cb, fd, &buf) != 0
+ || ((cb->to_fstat) (cb, fd, &buf) != 0
|| (buf.st_mode & S_IFIFO) == 0)
|| current_cpu->thread_data == NULL)
{
break;
}
+ case TARGET_SYS_access:
+ {
+ SI path = arg1;
+ SI mode = arg2;
+ char *pbuf = xmalloc (SIM_PATHMAX);
+ int i;
+ int o = 0;
+ int hmode = 0;
+
+ if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/')
+ {
+ strcpy (pbuf, simulator_sysroot);
+ o += strlen (simulator_sysroot);
+ }
+
+ for (i = 0; i + o < SIM_PATHMAX; i++)
+ {
+ pbuf[i + o]
+ = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i);
+ if (pbuf[i + o] == 0)
+ break;
+ }
+
+ if (i + o == SIM_PATHMAX)
+ {
+ retval = -cb_host_to_target_errno (cb, ENAMETOOLONG);
+ break;
+ }
+
+ /* Assert that we don't get calls for files for which we
+ don't have support. */
+ if (strncmp (pbuf + strlen (simulator_sysroot),
+ "/proc/", 6) == 0)
+ abort ();
+#define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
+ X_AFLAG (R_OK);
+ X_AFLAG (W_OK);
+ X_AFLAG (X_OK);
+ X_AFLAG (F_OK);
+#undef X_AFLAG
+
+ if (access (pbuf, hmode) != 0)
+ retval = -cb_host_to_target_errno (cb, errno);
+ else
+ retval = 0;
+
+ free (pbuf);
+ break;
+ }
+
case TARGET_SYS_readlink:
{
SI path = arg1;
retval = -cb_host_to_target_errno (cb, ENOSYS);
break;
+ case TARGET_SYS_set_thread_area:
+ /* Do the same error check as Linux. */
+ if (arg1 & 255)
+ {
+ retval = -cb_host_to_target_errno (cb, EINVAL);
+ break;
+ }
+ (*current_cpu->set_target_thread_data) (current_cpu, arg1);
+ retval = 0;
+ break;
+
unimplemented_syscall:
default:
retval
{
int i;
SIM_CPU *cpu = current_cpu_for_cb_callback;
+ SIM_DESC sd = CPU_STATE (current_cpu_for_cb_callback);
bfd_byte r10_buf[4];
int remaining
= cb->pipe_buffer[writer].size - cb->pipe_buffer[reader].size;