summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-03-03 03:34:55 +0000
committerGabe Black <gblack@eecs.umich.edu>2007-03-03 03:34:55 +0000
commit23dc5099a4bca9e38a286d867c4eccd7db3c09c1 (patch)
treea9b0c8d4d195b8bb2fe52258dfd1546673aa3706
parent477afcaf5b16068cdf9577ca9e9a407fb1b191a0 (diff)
downloadgem5-23dc5099a4bca9e38a286d867c4eccd7db3c09c1.tar.xz
Implement the _llseek syscall. It's Linux only, so we'll actually use the lseek syscall.
--HG-- extra : convert_revision : cccfd5efddbba527c6fb4e07ad2ab235a2670918
-rw-r--r--src/arch/sparc/linux/process.cc2
-rw-r--r--src/sim/syscall_emul.cc33
-rw-r--r--src/sim/syscall_emul.hh4
3 files changed, 38 insertions, 1 deletions
diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc
index 9c7c0e643..10cde3af8 100644
--- a/src/arch/sparc/linux/process.cc
+++ b/src/arch/sparc/linux/process.cc
@@ -333,7 +333,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 233 */ SyscallDesc("stime", unimplementedFunc),
/* 234 */ SyscallDesc("statfs64", unimplementedFunc),
/* 235 */ SyscallDesc("fstatfs64", unimplementedFunc),
- /* 236 */ SyscallDesc("_llseek", unimplementedFunc),
+ /* 236 */ SyscallDesc("_llseek", _llseekFunc),
/* 237 */ SyscallDesc("mlock", unimplementedFunc),
/* 238 */ SyscallDesc("munlock", unimplementedFunc),
/* 239 */ SyscallDesc("mlockall", unimplementedFunc),
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index ab44c0a35..876f39e99 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -184,6 +184,39 @@ lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
SyscallReturn
+_llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
+{
+ int fd = p->sim_fd(tc->getSyscallArg(0));
+ uint64_t offset_high = tc->getSyscallArg(1);
+ uint32_t offset_low = tc->getSyscallArg(2);
+ Addr result_ptr = tc->getSyscallArg(3);
+ int whence = tc->getSyscallArg(4);
+
+ uint64_t offset = (offset_high << 32) | offset_low;
+
+ uint64_t result = lseek(fd, offset, whence);
+ result = TheISA::htog(result);
+
+ if (result == (off_t)-1) {
+ //The seek failed.
+ return -errno;
+ } else {
+ //The seek succeeded.
+ //Copy "result" to "result_ptr"
+ //XXX We'll assume that the size of loff_t is 64 bits on the
+ //target platform
+ BufferArg result_buf(result_ptr, sizeof(result));
+ memcpy(result_buf.bufferPtr(), &result, sizeof(result));
+ result_buf.copyOut(tc->getMemPort());
+ return 0;
+ }
+
+
+ return (result == (off_t)-1) ? -errno : result;
+}
+
+
+SyscallReturn
munmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
// given that we don't really implement mmap, munmap is really easy
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index f57bd5272..5ca2f6be5 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -211,6 +211,10 @@ SyscallReturn writeFunc(SyscallDesc *desc, int num,
SyscallReturn lseekFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc);
+/// Target _llseek() handler.
+SyscallReturn _llseekFunc(SyscallDesc *desc, int num,
+ LiveProcess *p, ThreadContext *tc);
+
/// Target munmap() handler.
SyscallReturn munmapFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc);