* 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.
This commit is contained in:
Hans-Peter Nilsson
2006-10-02 03:21:28 +00:00
parent 1654a6f728
commit 466b1d3308
4 changed files with 198 additions and 112 deletions

View File

@ -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> 2006-09-30 Daniel Jacobowitz <dan@codesourcery.com>
* MAINTAINERS: Add Dave Brolley for sh64. * MAINTAINERS: Add Dave Brolley for sh64.

View File

@ -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, extern USI cris_break_13_handler (SIM_CPU *, USI, USI, USI, USI, USI, USI,
USI, USI); USI, USI);
extern char cris_have_900000xxif; 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 }; enum cris_interrupt_type { CRIS_INT_NMI, CRIS_INT_RESET, CRIS_INT_INT };
extern int crisv10deliver_interrupt (SIM_CPU *, extern int crisv10deliver_interrupt (SIM_CPU *,
enum cris_interrupt_type, enum cris_interrupt_type,

View File

@ -80,6 +80,10 @@ static char cris_bare_iron = 0;
/* Whether 0x9000000xx have simulator-specific meanings. */ /* Whether 0x9000000xx have simulator-specific meanings. */
char cris_have_900000xxif = 0; 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 /* Records simulator descriptor so utilities like cris_dump_regs can be
called from gdb. */ called from gdb. */
SIM_DESC current_state; SIM_DESC current_state;
@ -90,6 +94,7 @@ typedef enum {
OPTION_CRIS_TRACE, OPTION_CRIS_TRACE,
OPTION_CRIS_NAKED, OPTION_CRIS_NAKED,
OPTION_CRIS_900000XXIF, OPTION_CRIS_900000XXIF,
OPTION_CRIS_UNKNOWN_SYSCALL
} CRIS_OPTIONS; } CRIS_OPTIONS;
static const OPTION cris_options[] = static const OPTION cris_options[] =
@ -108,6 +113,10 @@ static const OPTION cris_options[] =
{ {"cris-900000xx", no_argument, NULL, OPTION_CRIS_900000XXIF}, { {"cris-900000xx", no_argument, NULL, OPTION_CRIS_900000XXIF},
'\0', NULL, "Define addresses at 0x900000xx with simulator semantics", '\0', NULL, "Define addresses at 0x900000xx with simulator semantics",
cris_option_handler, NULL }, 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 } { {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; *tracefp = FLAG_CRIS_MISC_PROFILE_ALL;
else else
{ {
/* We'll actually never get here; the caller handles the /* Beware; the framework does not handle the error case;
error case. */ we have to do it ourselves. */
sim_io_eprintf (sd, "Unknown option `--cris-stats=%s'\n", arg); sim_io_eprintf (sd, "Unknown option `--cris-cycles=%s'\n", arg);
return SIM_RC_FAIL; return SIM_RC_FAIL;
} }
break; break;
@ -177,6 +186,21 @@ cris_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
cris_have_900000xxif = 1; cris_have_900000xxif = 1;
break; 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: default:
/* We'll actually never get here; the caller handles the error /* We'll actually never get here; the caller handles the error
case. */ case. */

View File

@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "bfd.h" #include "bfd.h"
/* FIXME: get rid of targ-vals.h usage everywhere else. */ /* FIXME: get rid of targ-vals.h usage everywhere else. */
#include <stdarg.h>
#ifdef HAVE_ERRNO_H #ifdef HAVE_ERRNO_H
#include <errno.h> #include <errno.h>
#endif #endif
@ -1349,6 +1350,31 @@ make_first_thread (SIM_CPU *current_cpu)
abort (); 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. */ /* Main function: the handler of the "break 13" syscall insn. */
USI USI
@ -1467,16 +1493,17 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
/* Abort for all other cases. */ /* Nothing else is implemented. */
sim_io_eprintf (sd, "Unimplemented %s syscall " retval
"(fd: 0x%lx: cmd: 0x%lx arg: 0x%lx)\n", = cris_unknown_syscall (current_cpu, pc,
callnum == TARGET_SYS_fcntl "Unimplemented %s syscall "
? "fcntl" : "fcntl64", "(fd: 0x%lx: cmd: 0x%lx arg: "
(unsigned long) (USI) arg1, "0x%lx)\n",
(unsigned long) (USI) arg2, callnum == TARGET_SYS_fcntl
(unsigned long) (USI) arg3); ? "fcntl" : "fcntl64",
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, (unsigned long) (USI) arg1,
SIM_SIGILL); (unsigned long) (USI) arg2,
(unsigned long) (USI) arg3);
break; break;
} }
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) || (fd != (USI) -1 && prot != TARGET_PROT_READ)
|| pgoff != 0) || pgoff != 0)
{ {
sim_io_eprintf (sd, "Unimplemented mmap2 call " retval
"(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", = cris_unknown_syscall (current_cpu, pc,
(unsigned long) arg1, "Unimplemented mmap2 call "
(unsigned long) arg2, "(0x%lx, 0x%lx, 0x%lx, "
(unsigned long) arg3, "0x%lx, 0x%lx, 0x%lx)\n",
(unsigned long) arg4, (unsigned long) arg1,
(unsigned long) arg5, (unsigned long) arg2,
(unsigned long) arg6); (unsigned long) arg3,
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, (unsigned long) arg4,
SIM_SIGILL); (unsigned long) arg5,
(unsigned long) arg6);
break; break;
} }
else if (fd != (USI) -1) 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, || !is_mapped (sd, &current_cpu->highest_mmapped_page, addr,
len)) len))
{ {
sim_io_eprintf (sd, "Unimplemented mprotect call " retval
"(0x%lx, 0x%lx, 0x%lx)\n", = cris_unknown_syscall (current_cpu, pc,
(unsigned long) arg1, "Unimplemented mprotect call "
(unsigned long) arg2, "(0x%lx, 0x%lx, 0x%lx)\n",
(unsigned long) arg3); (unsigned long) arg1,
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, (unsigned long) arg2,
SIM_SIGILL); (unsigned long) arg3);
break; break;
} }
@ -1766,14 +1794,14 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|| rusagep != 0 || rusagep != 0
|| current_cpu->thread_data == NULL) || current_cpu->thread_data == NULL)
{ {
sim_io_eprintf (sd, "Unimplemented wait4 call " retval
"(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", = cris_unknown_syscall (current_cpu, pc,
(unsigned long) arg1, "Unimplemented wait4 call "
(unsigned long) arg2, "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
(unsigned long) arg3, (unsigned long) arg1,
(unsigned long) arg4); (unsigned long) arg2,
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, (unsigned long) arg3,
SIM_SIGILL); (unsigned long) arg4);
break; 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_flags != (TARGET_SA_RESTART|TARGET_SA_SIGINFO))
|| target_sa_handler == 0) || target_sa_handler == 0)
{ {
sim_io_eprintf (sd, "Unimplemented rt_sigaction " retval
"syscall (0x%lx, " = cris_unknown_syscall (current_cpu, pc,
"0x%lx: [0x%x, 0x%x, 0x%x, " "Unimplemented rt_sigaction "
"{0x%x, 0x%x}], " "syscall "
"0x%lx)\n", "(0x%lx, 0x%lx: "
(unsigned long) arg1, "[0x%x, 0x%x, 0x%x, "
(unsigned long) arg2, "{0x%x, 0x%x}], 0x%lx)\n",
target_sa_handler, target_sa_flags, (unsigned long) arg1,
target_sa_restorer, (unsigned long) arg2,
target_sa_mask_low, target_sa_mask_high, target_sa_handler,
(unsigned long) arg3); target_sa_flags,
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, target_sa_restorer,
SIM_SIGILL); target_sa_mask_low,
target_sa_mask_high,
(unsigned long) arg3);
break;
} }
current_cpu->sighandler[signum] = target_sa_handler; 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) || (buf.st_mode & S_IFIFO) == 0)
|| current_cpu->thread_data == NULL) || current_cpu->thread_data == NULL)
{ {
sim_io_eprintf (sd, "Unimplemented poll syscall " retval
"(0x%lx: [0x%x, 0x%x, x], 0x%lx, 0x%lx)\n", = cris_unknown_syscall (current_cpu, pc,
(unsigned long) arg1, fd, events, "Unimplemented poll syscall "
(unsigned long) arg2, (unsigned long) arg3); "(0x%lx: [0x%x, 0x%x, x], "
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL); "0x%lx, 0x%lx)\n",
(unsigned long) arg1, fd, events,
(unsigned long) arg2,
(unsigned long) arg3);
break; break;
} }
@ -2108,12 +2142,13 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
if (!((offs_hi == 0 && offs_lo >= 0) if (!((offs_hi == 0 && offs_lo >= 0)
|| (offs_hi == -1 && offs_lo < 0))) || (offs_hi == -1 && offs_lo < 0)))
{ {
sim_io_eprintf (sd, retval
"Unimplemented llseek offset," = cris_unknown_syscall (current_cpu, pc,
" fd %d: 0x%x:0x%x\n", "Unimplemented llseek offset,"
fd, (unsigned) arg2, (unsigned) arg3); " fd %d: 0x%x:0x%x\n",
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, fd, (unsigned) arg2,
SIM_SIGILL); (unsigned) arg3);
break;
} }
s.func = TARGET_SYS_lseek; 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_SETMASK
&& how != TARGET_SIG_UNBLOCK) && how != TARGET_SIG_UNBLOCK)
{ {
sim_io_eprintf (sd, "Unimplemented rt_sigprocmask syscall " retval
"(0x%x, 0x%x, 0x%x)\n", arg1, arg2, arg3); = cris_unknown_syscall (current_cpu, pc,
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, "Unimplemented rt_sigprocmask "
SIM_SIGILL); "syscall (0x%x, 0x%x, 0x%x)\n",
retval = 0; arg1, arg2, arg3);
break; 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 || (current_cpu->thread_data[threadno].cpu_context_atsignal
== NULL)) == NULL))
{ {
sim_io_eprintf (sd, "Invalid sigreturn syscall: no signal" retval
" handler active " = cris_unknown_syscall (current_cpu, pc,
"(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", "Invalid sigreturn syscall: "
(unsigned long) arg1, "no signal handler active "
(unsigned long) arg2, "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
(unsigned long) arg3, "0x%lx, 0x%lx)\n",
(unsigned long) arg4, (unsigned long) arg1,
(unsigned long) arg5, (unsigned long) arg2,
(unsigned long) arg6); (unsigned long) arg3,
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, (unsigned long) arg4,
SIM_SIGILL); (unsigned long) arg5,
(unsigned long) arg6);
break;
} }
was_sigsuspended was_sigsuspended
@ -2342,11 +2379,13 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
if (setsize != 8) if (setsize != 8)
{ {
sim_io_eprintf (sd, "Unimplemented rt_sigsuspend syscall" retval
" arguments (0x%lx, 0x%lx)\n", = cris_unknown_syscall (current_cpu, pc,
(unsigned long) arg1, (unsigned long) arg2); "Unimplemented rt_sigsuspend syscall"
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, " arguments (0x%lx, 0x%lx)\n",
SIM_SIGILL); (unsigned long) arg1,
(unsigned long) arg2);
break;
} }
/* Don't change the signal mask if we're already in /* 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 == '.') if (argv0 == NULL || *argv0 == '.')
{ {
sim_io_eprintf (sd, "Unimplemented readlink syscall " retval
"(0x%lx: [\"%s\"], 0x%lx)\n", = cris_unknown_syscall (current_cpu, pc,
(unsigned long) arg1, pbuf, "Unimplemented readlink syscall "
(unsigned long) arg2); "(0x%lx: [\"%s\"], 0x%lx)\n",
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, (unsigned long) arg1, pbuf,
SIM_SIGILL); (unsigned long) arg2);
break; break;
} }
else if (*argv0 == '/') else if (*argv0 == '/')
@ -2734,19 +2773,19 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
break; break;
} }
sim_io_eprintf (sd, "Unimplemented _sysctl syscall " retval
"(0x%lx: [0x%lx, 0x%lx]," = cris_unknown_syscall (current_cpu, pc,
" 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", "Unimplemented _sysctl syscall "
(unsigned long) name, "(0x%lx: [0x%lx, 0x%lx],"
(unsigned long) name0, " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
(unsigned long) name1, (unsigned long) name,
(unsigned long) nlen, (unsigned long) name0,
(unsigned long) oldval, (unsigned long) name1,
(unsigned long) oldlenp, (unsigned long) nlen,
(unsigned long) newval, (unsigned long) oldval,
(unsigned long) newlen); (unsigned long) oldlenp,
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, (unsigned long) newval,
SIM_SIGILL); (unsigned long) newlen);
break; break;
} }
@ -2819,11 +2858,13 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
| TARGET_CLONE_SIGHAND) | TARGET_CLONE_SIGHAND)
|| newsp == 0) || newsp == 0)
{ {
sim_io_eprintf (sd, retval
"Unimplemented clone syscall (0x%lx, 0x%lx)\n", = cris_unknown_syscall (current_cpu, pc,
(unsigned long) arg1, (unsigned long) arg2); "Unimplemented clone syscall "
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, "(0x%lx, 0x%lx)\n",
SIM_SIGILL); (unsigned long) arg1,
(unsigned long) arg2);
break;
} }
if (current_cpu->thread_data == NULL) if (current_cpu->thread_data == NULL)
@ -2886,11 +2927,12 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
unimplemented_syscall: unimplemented_syscall:
default: default:
sim_io_eprintf (sd, "Unimplemented syscall: %d " retval
"(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", callnum, = cris_unknown_syscall (current_cpu, pc,
arg1, arg2, arg3, arg4, arg5, arg6); "Unimplemented syscall: %d "
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
SIM_SIGILL); 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_fd = retval;
current_cpu->last_open_flags = arg2; current_cpu->last_open_flags = arg2;
} }
current_cpu->last_syscall = callnum; current_cpu->last_syscall = callnum;
/* A system call is a rescheduling point. For the time being, we don't /* A system call is a rescheduling point. For the time being, we don't