aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sim/ChangeLog16
-rw-r--r--sim/cris/cris-sim.h3
-rw-r--r--sim/cris/sim-if.c30
-rw-r--r--sim/cris/traps.c261
4 files changed, 198 insertions, 112 deletions
diff --git a/sim/ChangeLog b/sim/ChangeLog
index 1ab72cd..ac9d9e6 100644
--- a/sim/ChangeLog
+++ b/sim/ChangeLog
@@ -1,3 +1,19 @@
+2006-10-02 Edgar E. Iglesias <edgar@axis.com>
+ Hans-Peter Nilsson <hp@axis.com>
+
+ * cris/cris-sim.h (enum cris_unknown_syscall_action_type)
+ (cris_unknown_syscall_action): Declare.
+ * cris/sim-if.c (cris_unknown_syscall_action): Define.
+ (cris_options): Add cris-unknown-syscall option.
+ (cris_option_handler): Correct comment about and error message for
+ invalid --cris-cycles argument. Handle --cris-unknown-syscall.
+ * cris/traps.c: Include stdarg.h
+ (cris_unknown_syscall): New function.
+ (cris_break_13_handler): Instead of sim_io_eprintf and
+ sim_engine_halt, call cris_unknown_syscall to handle more or less
+ unknown syscalls. Adjust code as necessary to handle return
+ value.
+
2006-09-30 Daniel Jacobowitz <dan@codesourcery.com>
* MAINTAINERS: Add Dave Brolley for sh64.
diff --git a/sim/cris/cris-sim.h b/sim/cris/cris-sim.h
index 49a6f61..b2dc5b6 100644
--- a/sim/cris/cris-sim.h
+++ b/sim/cris/cris-sim.h
@@ -87,6 +87,9 @@ extern USI crisv32f_break_handler (SIM_CPU *, USI, USI);
extern USI cris_break_13_handler (SIM_CPU *, USI, USI, USI, USI, USI, USI,
USI, USI);
extern char cris_have_900000xxif;
+enum cris_unknown_syscall_action_type
+ { CRIS_USYSC_MSG_STOP, CRIS_USYSC_MSG_ENOSYS, CRIS_USYSC_QUIET_ENOSYS };
+extern enum cris_unknown_syscall_action_type cris_unknown_syscall_action;
enum cris_interrupt_type { CRIS_INT_NMI, CRIS_INT_RESET, CRIS_INT_INT };
extern int crisv10deliver_interrupt (SIM_CPU *,
enum cris_interrupt_type,
diff --git a/sim/cris/sim-if.c b/sim/cris/sim-if.c
index 86d19b2..bfa360c 100644
--- a/sim/cris/sim-if.c
+++ b/sim/cris/sim-if.c
@@ -80,6 +80,10 @@ static char cris_bare_iron = 0;
/* Whether 0x9000000xx have simulator-specific meanings. */
char cris_have_900000xxif = 0;
+/* What to do when we face a more or less unknown syscall. */
+enum cris_unknown_syscall_action_type cris_unknown_syscall_action
+ = CRIS_USYSC_MSG_STOP;
+
/* Records simulator descriptor so utilities like cris_dump_regs can be
called from gdb. */
SIM_DESC current_state;
@@ -90,6 +94,7 @@ typedef enum {
OPTION_CRIS_TRACE,
OPTION_CRIS_NAKED,
OPTION_CRIS_900000XXIF,
+ OPTION_CRIS_UNKNOWN_SYSCALL
} CRIS_OPTIONS;
static const OPTION cris_options[] =
@@ -108,6 +113,10 @@ static const OPTION cris_options[] =
{ {"cris-900000xx", no_argument, NULL, OPTION_CRIS_900000XXIF},
'\0', NULL, "Define addresses at 0x900000xx with simulator semantics",
cris_option_handler, NULL },
+ { {"cris-unknown-syscall", required_argument, NULL,
+ OPTION_CRIS_UNKNOWN_SYSCALL},
+ '\0', "stop|enosys|enosys-quiet", "Action at an unknown system call",
+ cris_option_handler, NULL },
{ {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
};
@@ -152,9 +161,9 @@ cris_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
*tracefp = FLAG_CRIS_MISC_PROFILE_ALL;
else
{
- /* We'll actually never get here; the caller handles the
- error case. */
- sim_io_eprintf (sd, "Unknown option `--cris-stats=%s'\n", arg);
+ /* Beware; the framework does not handle the error case;
+ we have to do it ourselves. */
+ sim_io_eprintf (sd, "Unknown option `--cris-cycles=%s'\n", arg);
return SIM_RC_FAIL;
}
break;
@@ -177,6 +186,21 @@ cris_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
cris_have_900000xxif = 1;
break;
+ case OPTION_CRIS_UNKNOWN_SYSCALL:
+ if (strcmp (arg, "enosys") == 0)
+ cris_unknown_syscall_action = CRIS_USYSC_MSG_ENOSYS;
+ else if (strcmp (arg, "enosys-quiet") == 0)
+ cris_unknown_syscall_action = CRIS_USYSC_QUIET_ENOSYS;
+ else if (strcmp (arg, "stop") == 0)
+ cris_unknown_syscall_action = CRIS_USYSC_MSG_STOP;
+ else
+ {
+ sim_io_eprintf (sd, "Unknown option `--cris-unknown-syscall=%s'\n",
+ arg);
+ return SIM_RC_FAIL;
+ }
+ break;
+
default:
/* We'll actually never get here; the caller handles the error
case. */
diff --git a/sim/cris/traps.c b/sim/cris/traps.c
index 371688f..3d80911 100644
--- a/sim/cris/traps.c
+++ b/sim/cris/traps.c
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "bfd.h"
/* FIXME: get rid of targ-vals.h usage everywhere else. */
+#include <stdarg.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -1349,6 +1350,31 @@ make_first_thread (SIM_CPU *current_cpu)
abort ();
}
+/* Handle unknown system calls. Returns (if it does) the syscall
+ return value. */
+
+static USI
+cris_unknown_syscall (SIM_CPU *current_cpu, USI pc, char *s, ...)
+{
+ SIM_DESC sd = CPU_STATE (current_cpu);
+ host_callback *cb = STATE_CALLBACK (sd);
+
+ if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP
+ || cris_unknown_syscall_action == CRIS_USYSC_MSG_ENOSYS)
+ {
+ va_list ap;
+
+ va_start (ap, s);
+ sim_io_evprintf (sd, s, ap);
+ va_end (ap);
+
+ if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP)
+ sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
+ }
+
+ return -cb_host_to_target_errno (cb, ENOSYS);
+}
+
/* Main function: the handler of the "break 13" syscall insn. */
USI
@@ -1467,16 +1493,17 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
}
/* FALLTHROUGH */
default:
- /* Abort for all other cases. */
- sim_io_eprintf (sd, "Unimplemented %s syscall "
- "(fd: 0x%lx: cmd: 0x%lx arg: 0x%lx)\n",
- callnum == TARGET_SYS_fcntl
- ? "fcntl" : "fcntl64",
- (unsigned long) (USI) arg1,
- (unsigned long) (USI) arg2,
- (unsigned long) (USI) arg3);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
+ /* Nothing else is implemented. */
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented %s syscall "
+ "(fd: 0x%lx: cmd: 0x%lx arg: "
+ "0x%lx)\n",
+ callnum == TARGET_SYS_fcntl
+ ? "fcntl" : "fcntl64",
+ (unsigned long) (USI) arg1,
+ (unsigned long) (USI) arg2,
+ (unsigned long) (USI) arg3);
break;
}
break;
@@ -1598,16 +1625,17 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|| (fd != (USI) -1 && prot != TARGET_PROT_READ)
|| pgoff != 0)
{
- sim_io_eprintf (sd, "Unimplemented mmap2 call "
- "(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
- (unsigned long) arg1,
- (unsigned long) arg2,
- (unsigned long) arg3,
- (unsigned long) arg4,
- (unsigned long) arg5,
- (unsigned long) arg6);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented mmap2 call "
+ "(0x%lx, 0x%lx, 0x%lx, "
+ "0x%lx, 0x%lx, 0x%lx)\n",
+ (unsigned long) arg1,
+ (unsigned long) arg2,
+ (unsigned long) arg3,
+ (unsigned long) arg4,
+ (unsigned long) arg5,
+ (unsigned long) arg6);
break;
}
else if (fd != (USI) -1)
@@ -1701,13 +1729,13 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|| !is_mapped (sd, &current_cpu->highest_mmapped_page, addr,
len))
{
- sim_io_eprintf (sd, "Unimplemented mprotect call "
- "(0x%lx, 0x%lx, 0x%lx)\n",
- (unsigned long) arg1,
- (unsigned long) arg2,
- (unsigned long) arg3);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented mprotect call "
+ "(0x%lx, 0x%lx, 0x%lx)\n",
+ (unsigned long) arg1,
+ (unsigned long) arg2,
+ (unsigned long) arg3);
break;
}
@@ -1766,14 +1794,14 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|| rusagep != 0
|| current_cpu->thread_data == NULL)
{
- sim_io_eprintf (sd, "Unimplemented wait4 call "
- "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
- (unsigned long) arg1,
- (unsigned long) arg2,
- (unsigned long) arg3,
- (unsigned long) arg4);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented wait4 call "
+ "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
+ (unsigned long) arg1,
+ (unsigned long) arg2,
+ (unsigned long) arg3,
+ (unsigned long) arg4);
break;
}
@@ -1879,19 +1907,22 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
&& target_sa_flags != (TARGET_SA_RESTART|TARGET_SA_SIGINFO))
|| target_sa_handler == 0)
{
- sim_io_eprintf (sd, "Unimplemented rt_sigaction "
- "syscall (0x%lx, "
- "0x%lx: [0x%x, 0x%x, 0x%x, "
- "{0x%x, 0x%x}], "
- "0x%lx)\n",
- (unsigned long) arg1,
- (unsigned long) arg2,
- target_sa_handler, target_sa_flags,
- target_sa_restorer,
- target_sa_mask_low, target_sa_mask_high,
- (unsigned long) arg3);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented rt_sigaction "
+ "syscall "
+ "(0x%lx, 0x%lx: "
+ "[0x%x, 0x%x, 0x%x, "
+ "{0x%x, 0x%x}], 0x%lx)\n",
+ (unsigned long) arg1,
+ (unsigned long) arg2,
+ target_sa_handler,
+ target_sa_flags,
+ target_sa_restorer,
+ target_sa_mask_low,
+ target_sa_mask_high,
+ (unsigned long) arg3);
+ break;
}
current_cpu->sighandler[signum] = target_sa_handler;
@@ -2012,11 +2043,14 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|| (buf.st_mode & S_IFIFO) == 0)
|| current_cpu->thread_data == NULL)
{
- sim_io_eprintf (sd, "Unimplemented poll syscall "
- "(0x%lx: [0x%x, 0x%x, x], 0x%lx, 0x%lx)\n",
- (unsigned long) arg1, fd, events,
- (unsigned long) arg2, (unsigned long) arg3);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented poll syscall "
+ "(0x%lx: [0x%x, 0x%x, x], "
+ "0x%lx, 0x%lx)\n",
+ (unsigned long) arg1, fd, events,
+ (unsigned long) arg2,
+ (unsigned long) arg3);
break;
}
@@ -2108,12 +2142,13 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
if (!((offs_hi == 0 && offs_lo >= 0)
|| (offs_hi == -1 && offs_lo < 0)))
{
- sim_io_eprintf (sd,
- "Unimplemented llseek offset,"
- " fd %d: 0x%x:0x%x\n",
- fd, (unsigned) arg2, (unsigned) arg3);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented llseek offset,"
+ " fd %d: 0x%x:0x%x\n",
+ fd, (unsigned) arg2,
+ (unsigned) arg3);
+ break;
}
s.func = TARGET_SYS_lseek;
@@ -2191,11 +2226,11 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
&& how != TARGET_SIG_SETMASK
&& how != TARGET_SIG_UNBLOCK)
{
- sim_io_eprintf (sd, "Unimplemented rt_sigprocmask syscall "
- "(0x%x, 0x%x, 0x%x)\n", arg1, arg2, arg3);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
- retval = 0;
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented rt_sigprocmask "
+ "syscall (0x%x, 0x%x, 0x%x)\n",
+ arg1, arg2, arg3);
break;
}
@@ -2266,17 +2301,19 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|| (current_cpu->thread_data[threadno].cpu_context_atsignal
== NULL))
{
- sim_io_eprintf (sd, "Invalid sigreturn syscall: no signal"
- " handler active "
- "(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
- (unsigned long) arg1,
- (unsigned long) arg2,
- (unsigned long) arg3,
- (unsigned long) arg4,
- (unsigned long) arg5,
- (unsigned long) arg6);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Invalid sigreturn syscall: "
+ "no signal handler active "
+ "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
+ "0x%lx, 0x%lx)\n",
+ (unsigned long) arg1,
+ (unsigned long) arg2,
+ (unsigned long) arg3,
+ (unsigned long) arg4,
+ (unsigned long) arg5,
+ (unsigned long) arg6);
+ break;
}
was_sigsuspended
@@ -2342,11 +2379,13 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
if (setsize != 8)
{
- sim_io_eprintf (sd, "Unimplemented rt_sigsuspend syscall"
- " arguments (0x%lx, 0x%lx)\n",
- (unsigned long) arg1, (unsigned long) arg2);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented rt_sigsuspend syscall"
+ " arguments (0x%lx, 0x%lx)\n",
+ (unsigned long) arg1,
+ (unsigned long) arg2);
+ break;
}
/* Don't change the signal mask if we're already in
@@ -2496,12 +2535,12 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
if (argv0 == NULL || *argv0 == '.')
{
- sim_io_eprintf (sd, "Unimplemented readlink syscall "
- "(0x%lx: [\"%s\"], 0x%lx)\n",
- (unsigned long) arg1, pbuf,
- (unsigned long) arg2);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented readlink syscall "
+ "(0x%lx: [\"%s\"], 0x%lx)\n",
+ (unsigned long) arg1, pbuf,
+ (unsigned long) arg2);
break;
}
else if (*argv0 == '/')
@@ -2734,19 +2773,19 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
break;
}
- sim_io_eprintf (sd, "Unimplemented _sysctl syscall "
- "(0x%lx: [0x%lx, 0x%lx],"
- " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
- (unsigned long) name,
- (unsigned long) name0,
- (unsigned long) name1,
- (unsigned long) nlen,
- (unsigned long) oldval,
- (unsigned long) oldlenp,
- (unsigned long) newval,
- (unsigned long) newlen);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented _sysctl syscall "
+ "(0x%lx: [0x%lx, 0x%lx],"
+ " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
+ (unsigned long) name,
+ (unsigned long) name0,
+ (unsigned long) name1,
+ (unsigned long) nlen,
+ (unsigned long) oldval,
+ (unsigned long) oldlenp,
+ (unsigned long) newval,
+ (unsigned long) newlen);
break;
}
@@ -2819,11 +2858,13 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
| TARGET_CLONE_SIGHAND)
|| newsp == 0)
{
- sim_io_eprintf (sd,
- "Unimplemented clone syscall (0x%lx, 0x%lx)\n",
- (unsigned long) arg1, (unsigned long) arg2);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented clone syscall "
+ "(0x%lx, 0x%lx)\n",
+ (unsigned long) arg1,
+ (unsigned long) arg2);
+ break;
}
if (current_cpu->thread_data == NULL)
@@ -2886,11 +2927,12 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
unimplemented_syscall:
default:
- sim_io_eprintf (sd, "Unimplemented syscall: %d "
- "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", callnum,
- arg1, arg2, arg3, arg4, arg5, arg6);
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
- SIM_SIGILL);
+ retval
+ = cris_unknown_syscall (current_cpu, pc,
+ "Unimplemented syscall: %d "
+ "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
+ callnum, arg1, arg2, arg3, arg4, arg5,
+ arg6);
}
}
@@ -2900,6 +2942,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
current_cpu->last_open_fd = retval;
current_cpu->last_open_flags = arg2;
}
+
current_cpu->last_syscall = callnum;
/* A system call is a rescheduling point. For the time being, we don't