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

Reply via email to