This isn't a real hg commit as this patch needs some work before it can be
committed (and I should split it up into its component parts).
It implements truncate64, makes an x86 fix to ftruncate64, and then hooks
up the syscalls for x86/x86_64.
This syscall is needed for the various fortran-90 spec2k benchmarks.
The truncate64 and ftruncate64 syscalls take a 64-bit value split across
2-registers on 32-bit machines, and then inside the kernel are merged into
a proper 64-bit value before use.
On some architectures when passing a 64-bit value like this, the registers
have to be paired even/odd.
The existing code makes assumptions about this pairing, and also seems to
ignore endianess issues as well as the top 32-bit of the 64-bit values,
but I might be misunderstanding how the argument passing in the system
calls works. I tried to get this right in this patch for x86, but it
possibly needs looking at for other architectures.
For what it's worth, qemu has a macro of the type
target_offset64(arg2, arg3)
which handles arguments of this type so that the shifting doesn't have to
be done by hand.
I've tested that truncate/ftruncate/truncate64/ftrucate64 work on
x86/x86_64 as they do on real machines.
Vince
diff -r cdaa1c9f6f02 src/arch/x86/linux/syscalls.cc
--- a/src/arch/x86/linux/syscalls.cc Sat Oct 24 17:15:31 2009 -0400
+++ b/src/arch/x86/linux/syscalls.cc Sat Oct 24 18:12:17 2009 -0400
@@ -304,8 +304,8 @@
/* 73 */ SyscallDesc("flock", unimplementedFunc),
/* 74 */ SyscallDesc("fsync", unimplementedFunc),
/* 75 */ SyscallDesc("fdatasync", unimplementedFunc),
- /* 76 */ SyscallDesc("truncate", unimplementedFunc),
- /* 77 */ SyscallDesc("ftruncate", unimplementedFunc),
+ /* 76 */ SyscallDesc("truncate", truncateFunc),
+ /* 77 */ SyscallDesc("ftruncate", ftruncateFunc),
/* 78 */ SyscallDesc("getdents", unimplementedFunc),
/* 79 */ SyscallDesc("getcwd", unimplementedFunc),
/* 80 */ SyscallDesc("chdir", unimplementedFunc),
@@ -599,8 +599,8 @@
/* 89 */ SyscallDesc("readdir", unimplementedFunc),
/* 90 */ SyscallDesc("mmap", unimplementedFunc),
/* 91 */ SyscallDesc("munmap", munmapFunc),
- /* 92 */ SyscallDesc("truncate", unimplementedFunc),
- /* 93 */ SyscallDesc("ftruncate", unimplementedFunc),
+ /* 92 */ SyscallDesc("truncate", truncateFunc),
+ /* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
/* 94 */ SyscallDesc("fchmod", unimplementedFunc),
/* 95 */ SyscallDesc("fchown", unimplementedFunc),
/* 96 */ SyscallDesc("getpriority", unimplementedFunc),
@@ -700,8 +700,8 @@
/* 190 */ SyscallDesc("vfork", unimplementedFunc),
/* 191 */ SyscallDesc("ugetrlimit", ignoreFunc),
/* 192 */ SyscallDesc("mmap2", mmapFunc<X86Linux32>),
- /* 193 */ SyscallDesc("truncate64", unimplementedFunc),
- /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc),
+ /* 193 */ SyscallDesc("truncate64", truncate64Func),
+ /* 194 */ SyscallDesc("ftruncate64", ftruncate64Func),
/* 195 */ SyscallDesc("stat64", stat64Func<X86Linux32>),
/* 196 */ SyscallDesc("lstat64", unimplementedFunc),
/* 197 */ SyscallDesc("fstat64", fstat64Func<X86Linux32>),
diff -r cdaa1c9f6f02 src/sim/syscall_emul.cc
--- a/src/sim/syscall_emul.cc Sat Oct 24 17:15:31 2009 -0400
+++ b/src/sim/syscall_emul.cc Sat Oct 24 18:12:17 2009 -0400
@@ -423,6 +423,32 @@
}
SyscallReturn
+truncate64Func(SyscallDesc *desc, int num,
+ LiveProcess *process, ThreadContext *tc)
+{
+
+ string path;
+
+ if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
+ return -EFAULT;
+
+#if THE_ISA == X86_ISA
+ loff_t length = (process->getSyscallArg(tc, 2)<<32) +
+ process->getSyscallArg(tc, 1);
+#else
+ /* big endian reg-algined vaue for PPC? */
+ loff_t length = process->getSyscallArg(tc, 3);
+#endif
+
+ // Adjust path for current working directory
+ path = process->fullPath(path);
+
+ int result = truncate64(path.c_str(), length);
+ return (result == -1) ? -errno : result;
+}
+
+
+SyscallReturn
ftruncate64Func(SyscallDesc *desc, int num,
LiveProcess *process, ThreadContext *tc)
{
@@ -431,9 +457,15 @@
if (fd < 0)
return -EBADF;
- // I'm not sure why, but the length argument is in arg reg 3
+#if THE_ISA == X86_ISA
+ /* construct little-endian 64-bit value */
+ loff_t length = (process->getSyscallArg(tc, 2) << 32) +
+ process->getSyscallArg(tc, 1);
+#else
+ /* big-endian reg-aligned value for PPC? */
loff_t length = process->getSyscallArg(tc, 3);
-
+#endif
+
int result = ftruncate64(fd, length);
return (result == -1) ? -errno : result;
}
diff -r cdaa1c9f6f02 src/sim/syscall_emul.hh
--- a/src/sim/syscall_emul.hh Sat Oct 24 17:15:31 2009 -0400
+++ b/src/sim/syscall_emul.hh Sat Oct 24 18:12:17 2009 -0400
@@ -261,6 +261,11 @@
/// Target ftruncate64() handler.
+SyscallReturn truncate64Func(SyscallDesc *desc, int num,
+ LiveProcess *p, ThreadContext *tc);
+
+
+/// Target ftruncate64() handler.
SyscallReturn ftruncate64Func(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc);
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev