* cris/sim-main.h (struct _sim_cpu): New members last_syscall,

last_open_fd, last_open_flags.
	* cris/traps.c: Don't include targ-vals.h.
	(TARGET_O_ACCMODE): Define.
	(cris_break_13_handler): Set new _sim_cpu members.
	<case TARGET_SYS_fcntl>: Support special case of F_GETFL.
	Rearrange code as switch.  Emit "unimplemented" abort for
	unimplemented fcntl calls.
This commit is contained in:
Hans-Peter Nilsson 2005-11-17 16:14:53 +00:00
parent 5457266c93
commit ed1f044ac6
3 changed files with 61 additions and 5 deletions

View file

@ -1,5 +1,14 @@
2005-11-17 Hans-Peter Nilsson <hp@axis.com>
* cris/sim-main.h (struct _sim_cpu): New members last_syscall,
last_open_fd, last_open_flags.
* cris/traps.c: Don't include targ-vals.h.
(TARGET_O_ACCMODE): Define.
(cris_break_13_handler): Set new _sim_cpu members.
<case TARGET_SYS_fcntl>: Support special case of F_GETFL.
Rearrange code as switch. Emit "unimplemented" abort for
unimplemented fcntl calls.
* cris/traps.c (TARGET_SYS_stat): Define.
(syscall_stat32_map): Add entry for TARGET_SYS_stat.
(cris_break_13_handler) <case TARGET_SYS_stat>: New case.

View file

@ -166,6 +166,17 @@ struct _sim_cpu {
for sigmasks and sigpendings. */
USI sighandler[64];
/* This is a hack to implement just the parts of fcntl F_GETFL that
are used in open+fdopen calls for the standard scenario: for such
a call we check that the last syscall was open, we check that the
passed fd is the same returned then, and so we return the same
flags passed to open. This way, we avoid complicating the
generic sim callback machinery by introducing fcntl
mechanisms. */
USI last_syscall;
USI last_open_fd;
USI last_open_flags;
/* Function for initializing CPU thread context, which varies in size
with each CPU model. They should be in some constant parts or
initialized in *_init_cpu, but we can't modify that for now. */

View file

@ -20,8 +20,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "sim-main.h"
#include "sim-options.h"
#include "targ-vals.h"
#include "bfd.h"
/* FIXME: get rid of targ-vals.h usage everywhere else. */
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@ -663,6 +664,9 @@ static const CB_TARGET_DEFS_MAP errno_map[] =
installation and removing synonyms and unnecessary items. Don't
forget the end-marker. */
/* This one we treat specially, as it's used in the fcntl syscall. */
#define TARGET_O_ACCMODE 3
static const CB_TARGET_DEFS_MAP open_map[] = {
#ifdef O_ACCMODE
{ O_ACCMODE, 0x3 },
@ -1399,8 +1403,9 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
case TARGET_SYS_fcntl64:
case TARGET_SYS_fcntl:
if (arg2 == 1)
switch (arg2)
{
case 1:
/* F_GETFD.
Glibc checks stdin, stdout and stderr fd:s for
close-on-exec security sanity. We just need to provide a
@ -1408,12 +1413,35 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
close-on-exec flag true, we could just do a real fcntl
here. */
retval = 0;
}
else if (arg2 == 2)
{
break;
case 2:
/* F_SETFD. Just ignore attempts to set the close-on-exec
flag. */
retval = 0;
break;
case 3:
/* F_GETFL. Check for the special case for open+fdopen. */
if (current_cpu->last_syscall == TARGET_SYS_open
&& arg1 == current_cpu->last_open_fd)
{
retval = current_cpu->last_open_flags & TARGET_O_ACCMODE;
break;
}
/* FALLTHROUGH */
/* Abort for all other cases. */
default:
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);
break;
}
break;
@ -2819,6 +2847,14 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
}
}
/* Minimal support for fcntl F_GETFL as used in open+fdopen. */
if (callnum == TARGET_SYS_open)
{
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
reschedule anywhere else. */
if (current_cpu->m1threads != 0