diff options
-rw-r--r-- | src/sim/emul_driver.hh | 15 | ||||
-rw-r--r-- | src/sim/syscall_emul.hh | 12 |
2 files changed, 24 insertions, 3 deletions
diff --git a/src/sim/emul_driver.hh b/src/sim/emul_driver.hh index 778fc6461..62ba61507 100644 --- a/src/sim/emul_driver.hh +++ b/src/sim/emul_driver.hh @@ -46,8 +46,8 @@ class ThreadContext; * hardware inside gem5 can be created by deriving from this class and * overriding the abstract virtual methods. * - * Currently only open() and ioctl() calls are supported, but other calls - * (e.g., read(), write(), mmap()) could be added as needed. + * Currently only open(), ioctl(), and mmap() calls are supported, but other + * calls (e.g., read(), write()) could be added as needed. */ class EmulatedDriver : public SimObject { @@ -85,6 +85,17 @@ class EmulatedDriver : public SimObject * (see the SyscallReturn class). */ virtual int ioctl(LiveProcess *p, ThreadContext *tc, unsigned req) = 0; + + /** + * Virtual method, invoked when the user program calls mmap() on + * the file descriptor returned by a previous open(). The parameters + * are the same as those passed in to mmapFunc() (q.v.). + * @return The return ptr for the mmap, or the negation of the errno + * (see the SyscallReturn class). + */ + virtual Addr mmap(LiveProcess *p, ThreadContext *tc, Addr start, + uint64_t length, int prot, int tgtFlags, int tgtFd, + int offset) { return -EBADF; } }; #endif // __SIM_EMUL_DRIVER_HH diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 7cce9e9c0..c11e9865f 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -1284,7 +1284,17 @@ mmapImpl(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc, int sim_fd = -1; uint8_t *pmap = nullptr; if (!(tgt_flags & OS::TGT_MAP_ANONYMOUS)) { - sim_fd = p->getSimFD(tgt_fd); + // Check for EmulatedDriver mmap + FDEntry *fde = p->getFDEntry(tgt_fd); + if (fde == NULL) + return -EBADF; + + if (fde->driver != NULL) { + return fde->driver->mmap(p, tc, start, length, prot, + tgt_flags, tgt_fd, offset); + } + sim_fd = fde->fd; + if (sim_fd < 0) return -EBADF; |