This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Committed: sim/cris: support open+fdopen syscall sequence.
- From: Hans-Peter Nilsson <hans-peter dot nilsson at axis dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 17 Nov 2005 17:21:40 +0100
- Subject: Committed: sim/cris: support open+fdopen syscall sequence.
This supports a kind of open+fdopen sequence used in bzip2.
That sequence allegedly fixes a race condition appearing with
plain fopen, so perhaps it'll be seen in other programs that one
may want to run in a simulator. Of course, I *could've*
introduced fcntl support in the callback machinery including
mapping forth and back and whatnot, but I don't think the added
complexity would do much good.
sim/:
* 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.
Index: cris/sim-main.h
===================================================================
RCS file: /cvs/src/src/sim/cris/sim-main.h,v
retrieving revision 1.2
diff -p -u -r1.2 sim-main.h
--- cris/sim-main.h 24 Mar 2005 06:12:42 -0000 1.2
+++ cris/sim-main.h 17 Nov 2005 16:13:04 -0000
@@ -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. */
Index: cris/traps.c
===================================================================
RCS file: /cvs/src/src/sim/cris/traps.c,v
retrieving revision 1.4
diff -p -u -r1.4 traps.c
--- cris/traps.c 17 Nov 2005 15:51:24 -0000 1.4
+++ cris/traps.c 17 Nov 2005 16:13:06 -0000
@@ -20,8 +20,9 @@ with this program; if not, write to the
#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_ma
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_
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_
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_
}
}
+ /* 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
brgds, H-P