From ed1f044ac6423184b2e2b8f805ddc4f76ea1256c Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Thu, 17 Nov 2005 16:14:53 +0000 Subject: [PATCH] * 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. : Support special case of F_GETFL. Rearrange code as switch. Emit "unimplemented" abort for unimplemented fcntl calls. --- sim/ChangeLog | 9 +++++++++ sim/cris/sim-main.h | 11 +++++++++++ sim/cris/traps.c | 46 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/sim/ChangeLog b/sim/ChangeLog index 9bc31eba5b9..e552e10aaaf 100644 --- a/sim/ChangeLog +++ b/sim/ChangeLog @@ -1,5 +1,14 @@ 2005-11-17 Hans-Peter Nilsson + * 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. + : 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) : New case. diff --git a/sim/cris/sim-main.h b/sim/cris/sim-main.h index b6715330065..b35b927278e 100644 --- a/sim/cris/sim-main.h +++ b/sim/cris/sim-main.h @@ -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. */ diff --git a/sim/cris/traps.c b/sim/cris/traps.c index 11cfaae95a0..607f72c6345 100644 --- a/sim/cris/traps.c +++ b/sim/cris/traps.c @@ -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 #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 -- 2.30.2