Commit f75b8bd8 authored by Ramon Nou's avatar Ramon Nou
Browse files

mmap / msync / munmap minimum support

parent 7294f884
Loading
Loading
Loading
Loading
+127 −55
Original line number Diff line number Diff line
@@ -58,14 +58,16 @@ std::atomic<bool> initializing{false};
#ifdef GKFS_TRACE
#define DEBUG_INFO(...)                                                        \
    do {                                                                       \
        fprintf(stderr, "[DEBUG] [GKFS] %s:%d: ", __FILE__, __LINE__);         \
        fprintf(stderr, __VA_ARGS__);                                          \
        LOG(DEBUG, __VA_ARGS__);                                               \
    } while(0)
#else
#define DEBUG_INFO(...) /* No debug output */
#endif
#endif
#define GKFS_DEBUG(...) DEBUG_INFO(__VA_ARGS__)


// set to store void * addr, fd, length and offset
std::set<std::tuple<void*, int, size_t, off_t>> mmap_set;

void
initializeGekko() {
@@ -85,7 +87,7 @@ initializeGekko() {

void
log_arguments(const char* symbol) {
    LOG(DEBUG, "[BYPASS] {}", symbol);
    DEBUG_INFO("[BYPASS] {}", symbol);
    // printf("[BYPASS] %s\n",symbol);
}

@@ -96,7 +98,7 @@ log_arguments(const char* symbol, Args&&... args) {
    std::stringstream ss;
    ss << "[BYPASS] Calling " << symbol << " with arguments: ";
    ((ss << "[" << typeid(Args).name() << "] " << args << " "), ...);
    LOG(DEBUG, "{}", ss.str());
    DEBUG_INFO("{}", ss.str());
    // printf("%s\n",ss.str().c_str());
}

@@ -107,7 +109,7 @@ log_argumentsx(const char* symbol, Args&&... args) {
    std::stringstream ss;
    ss << "[BYPASS-ERROR] Calling " << symbol << " with arguments: ";
    ((ss << "[" << typeid(Args).name() << "] " << args << " "), ...);
    LOG(DEBUG, "{}", ss.str());
    DEBUG_INFO("{}", ss.str());
    // printf("%s\n",ss.str().c_str());
}

@@ -274,6 +276,10 @@ DLSYM_WRAPPER(void*, mmap,
              (void* addr, size_t length, int prot, int flags, int fd,
               off_t offset),
              (addr, length, prot, flags, fd, offset), "mmap")
DLSYM_WRAPPER(int, msync, (void* addr, size_t length, int flags),
              (addr, length, flags), "msync")
DLSYM_WRAPPER(int, munmap, (void* addr, size_t length), (addr, length),
              "munmap")
DLSYM_WRAPPER(FILE*, fopen, (const char* filename, const char* mode),
              (filename, mode), "fopen")
DLSYM_WRAPPER(FILE*, fdopen, (int fd, const char* mode), (fd, mode), "fdopen")
@@ -326,11 +332,12 @@ CDLSYM_WRAPPER(int, fexecve, (int fd, const char* filename, char* const argv[]),
DLSYM_WRAPPER(long, syscall, (long number, char* cmd, void* arg, void* env),
              (number, cmd, arg, env), "syscall")


long
syscall(long number, ...) {

    if(number == SYS_execve or number == SYS_execveat) {
        LOG(DEBUG, "execve {}", number);
        DEBUG_INFO("execve {}", number);
    }
    va_list myargs;
    va_start(myargs, number);
@@ -442,7 +449,7 @@ is_gkfs_fd(int fd) {

#define GKFS_OPERATION(name, ...)                                              \
    if(CTX->interception_enabled() && is_gkfs_fd(fd)) {                        \
        LOG(DEBUG, "[GKFS] {}", fd);                                           \
        DEBUG_INFO("[GKFS] {}", fd);                                           \
        return gkfs::syscall::gkfs_##name(__VA_ARGS__);                        \
    }

@@ -451,7 +458,7 @@ is_gkfs_fd(int fd) {
        std::string resolved;                                                  \
        switch(resolve_gkfs_path(dirfd, path, resolved)) {                     \
            case PathStatus::Internal:                                         \
                LOG(DEBUG, "[GKFS] {}", resolved);                             \
                DEBUG_INFO("[GKFS] {}", resolved);                             \
                return gkfs::syscall::gkfs_##name(resolved, __VA_ARGS__);      \
            case PathStatus::Error:                                            \
                return -errno;                                                 \
@@ -465,7 +472,7 @@ is_gkfs_fd(int fd) {
        std::string resolved;                                                  \
        switch(resolve_gkfs_path(dirfd, path, resolved)) {                     \
            case PathStatus::Internal:                                         \
                LOG(DEBUG, "[GKFS] {}", resolved);                             \
                DEBUG_INFO("[GKFS] {}", resolved);                             \
                return gkfs::syscall::gkfs_##name(dirfd, resolved,             \
                                                  __VA_ARGS__);                \
            case PathStatus::Error:                                            \
@@ -480,7 +487,7 @@ is_gkfs_fd(int fd) {
        std::string resolved;                                                  \
        switch(resolve_gkfs_path(dirfd, path, resolved)) {                     \
            case PathStatus::Internal:                                         \
                LOG(DEBUG, "[GKFS] {}", resolved);                             \
                DEBUG_INFO("[GKFS] {}", resolved);                             \
                return gkfs::syscall::gkfs_##name(resolved);                   \
            case PathStatus::Error:                                            \
                return -errno;                                                 \
@@ -598,13 +605,13 @@ get_open_fds() {

int
close_range(unsigned low, unsigned high, int flags) {
    LOG(DEBUG, "close_range({}, {}, {})", low, high, flags);
    DEBUG_INFO("close_range({}, {}, {})", low, high, flags);
    return 0;
    auto fds = get_open_fds();
#ifdef CLOSE_RANGE_UNSHARE
    if(flags & CLOSE_RANGE_UNSHARE) {
        // Unshare the file descriptor table
        LOG(DEBUG, "close_range with CLOSE_RANGE_UNSHARE");
        DEBUG_INFO("close_range with CLOSE_RANGE_UNSHARE");
        if(unshare(CLONE_FILES) == -1) {
            perror("unshare() failed");
            return -1;
@@ -614,7 +621,7 @@ close_range(unsigned low, unsigned high, int flags) {
#ifdef CLOSE_RANGE_CLOEXEC
    if(flags & CLOSE_RANGE_CLOEXEC) {
        // Close all file descriptors in the range
        LOG(DEBUG, "close_range with CLOSE_RANGE_CLOEXEC");
        DEBUG_INFO("close_range with CLOSE_RANGE_CLOEXEC");
    }
#endif
    // Is fd from gekkofs ?
@@ -662,7 +669,7 @@ ftruncate(int fd, off_t length) {
    initializeGekko();
    if(is_gkfs_fd(fd)) {
        std::string path_str = CTX->file_map()->get(fd)->path();
        LOG(DEBUG, "[GKFS] {}", path_str);
        DEBUG_INFO("[GKFS] {}", path_str);
        return gkfs::syscall::gkfs_truncate(path_str, length);
    }
    GKFS_FALLBACK(ftruncate, fd, length);
@@ -767,7 +774,7 @@ __xstat64(int ver, const char* path, struct stat64* buf) {
        std::string resolved;
        switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) {
            case PathStatus::Internal: {
                LOG(DEBUG, "[GKFS] {}", resolved);
                DEBUG_INFO("[GKFS] {}", resolved);
                auto res = gkfs::syscall::gkfs_stat(resolved, &st);
                convert(&st, buf);
                return res;
@@ -809,7 +816,7 @@ __lxstat(int ver, const char* path, struct stat* buf) {
        std::string resolved;
        switch(resolve_gkfs_path(AT_FDCWD, path, resolved, 0, false)) {
            case PathStatus::Internal: {
                LOG(DEBUG, "[GKFS] {}", resolved);
                DEBUG_INFO("[GKFS] {}", resolved);
                auto res = gkfs::syscall::gkfs_stat(resolved, buf);
                return res;
            }
@@ -832,7 +839,7 @@ __lxstat64(int ver, const char* path, struct stat64* buf) {
        std::string resolved;
        switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) {
            case PathStatus::Internal: {
                LOG(DEBUG, "[GKFS] {}", resolved);
                DEBUG_INFO("[GKFS] {}", resolved);
                auto res = gkfs::syscall::gkfs_stat(resolved, &st);
                convert(&st, buf);
                return res;
@@ -851,7 +858,7 @@ int
__fxstat(int ver, int fd, struct stat* buf) {
    initializeGekko();
    if(is_gkfs_fd(fd)) {
        LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path());
        DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path());
        return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf);
    }
    GKFS_FALLBACK(fstat, ver, fd, buf);
@@ -869,7 +876,7 @@ __fxstat64(int ver, int fd, struct stat64* buf) {
    initializeGekko();
    if(is_gkfs_fd(fd)) {
        struct stat st;
        LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path());
        DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path());
        int res =
                gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), &st);
        if(res == 0)
@@ -884,7 +891,7 @@ fstat64(int fd, struct stat64* buf) {
    initializeGekko();
    if(is_gkfs_fd(fd)) {
        struct stat st;
        LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path());
        DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path());
        int res =
                gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), &st);
        if(res == 0)
@@ -904,7 +911,7 @@ __fxstatat64(int ver, int dfd, const char* path, struct stat64* buf,
        std::string resolved;
        switch(resolve_gkfs_path(dfd, path, resolved)) {
            case PathStatus::Internal: {
                LOG(DEBUG, "[GKFS] {}", resolved);
                DEBUG_INFO("[GKFS] {}", resolved);
                auto res = gkfs::syscall::gkfs_stat(resolved, &st);
                convert(&st, buf);
                return res;
@@ -934,7 +941,7 @@ stat64(const char* path, struct stat64* buf) {
        std::string resolved;
        switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) {
            case PathStatus::Internal: {
                LOG(DEBUG, "[GKFS] {}", resolved);
                DEBUG_INFO("[GKFS] {}", resolved);
                auto res = gkfs::syscall::gkfs_stat(resolved, &st);
                convert(&st, buf);
                return res;
@@ -956,7 +963,7 @@ int
fstat(int fd, struct stat* buf) {
    initializeGekko();
    if(is_gkfs_fd(fd)) {
        LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path());
        DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path());
        return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf);
    }
    GKFS_FALLBACK(fstat, _STAT_VER, fd, buf);
@@ -969,7 +976,7 @@ fstatat(int dfd, const char* path, struct stat* buf, int flags) {
        std::string resolved;
        switch(resolve_gkfs_path(dfd, path, resolved)) {
            case PathStatus::Internal: {
                LOG(DEBUG, "[GKFS] {}", resolved);
                DEBUG_INFO("[GKFS] {}", resolved);
                auto res = gkfs::syscall::gkfs_stat(resolved, buf);
                return res;
            }
@@ -999,7 +1006,7 @@ rename(const char* oldpath, const char* newpath) {
            case PathStatus::Internal:
                switch(rstatus_new) {
                    case PathStatus::Internal:
                        LOG(DEBUG, "[GKFS] {} {}{}", "NOT IMPLEMENTED",
                        DEBUG_INFO("[GKFS] {} {}{}", "NOT IMPLEMENTED",
                                   resolved_old, resolved_new);
                        return -ENOTDIR;
                        //                       return
@@ -1050,7 +1057,7 @@ pipe(int pipefd[2]) {
    initializeGekko();

    auto res = dlsym_pipe(pipefd);
    LOG(DEBUG, "pipe {} <---> {}", pipefd[0], pipefd[1]);
    DEBUG_INFO("pipe {} <---> {}", pipefd[0], pipefd[1]);

    // GKFS_FALLBACK(pipe, pipefd);
    return res;
@@ -1067,13 +1074,13 @@ int
dup2(int fd, int fd2) {
    initializeGekko();
    if(is_gkfs_fd(fd) && is_gkfs_fd(fd2)) {
        LOG(DEBUG, "[GKFS] DUP2 G{} --> G{}", fd, fd2);
        DEBUG_INFO("[GKFS] DUP2 G{} --> G{}", fd, fd2);
        return gkfs::syscall::gkfs_dup2(fd, fd2);
    } else if(is_gkfs_fd(fd2)) {
        LOG(DEBUG, "[GKFS-NON] DUP2 {} --> G{}", fd, fd2);
        DEBUG_INFO("[GKFS-NON] DUP2 {} --> G{}", fd, fd2);
        return gkfs::syscall::gkfs_dup(fd);
    } else if(is_gkfs_fd(fd)) {
        LOG(DEBUG, "[GKFS-NON] DUP2 G{} --> {}", fd, fd2);
        DEBUG_INFO("[GKFS-NON] DUP2 G{} --> {}", fd, fd2);
        return gkfs::syscall::gkfs_dup2(fd, fd2);
    }

@@ -1114,7 +1121,7 @@ chdir(const char* path) {
                return -ENOTDIR;

            case gkfs::preload::RelativizeStatus::internal:
                LOG(DEBUG, "[GKFS] NOT IMPLEMENTED {}", path);
                DEBUG_INFO("[GKFS] NOT IMPLEMENTED {}", path);
                break;

            default:
@@ -1138,12 +1145,12 @@ fcntl(int fd, int cmd, long arg) // TODO
        switch(cmd) {

            case F_DUPFD:
                LOG(DEBUG, "[GKFS] DUPFD {}", fd);
                DEBUG_INFO("[GKFS] DUPFD {}", fd);

                return gkfs::syscall::gkfs_dup(fd);

            case F_DUPFD_CLOEXEC:
                LOG(DEBUG, "[GKFS] F_DUPFD_CLOEXEC {}", fd);
                DEBUG_INFO("[GKFS] F_DUPFD_CLOEXEC {}", fd);
                ret = gkfs::syscall::gkfs_dup(fd);
                if(ret == -1) {
                    return -errno;
@@ -1153,7 +1160,7 @@ fcntl(int fd, int cmd, long arg) // TODO
                return ret;

            case F_GETFD:
                LOG(DEBUG, "[GKFS] F_GETFD {}", fd);
                DEBUG_INFO("[GKFS] F_GETFD {}", fd);
                if(CTX->file_map()->get(fd)->get_flag(
                           gkfs::filemap::OpenFile_flags::cloexec)) {
                    return FD_CLOEXEC;
@@ -1161,7 +1168,7 @@ fcntl(int fd, int cmd, long arg) // TODO
                return 0;

            case F_GETFL:
                LOG(DEBUG, "[GKFS] F_GETFL {}", fd);
                DEBUG_INFO("[GKFS] F_GETFL {}", fd);
                ret = 0;
                if(CTX->file_map()->get(fd)->get_flag(
                           gkfs::filemap::OpenFile_flags::rdonly)) {
@@ -1178,18 +1185,18 @@ fcntl(int fd, int cmd, long arg) // TODO
                return ret;

            case F_SETFD:
                LOG(DEBUG, "[GKFS] F_SETFD {}", fd);
                DEBUG_INFO("[GKFS] F_SETFD {}", fd);
                CTX->file_map()->get(fd)->set_flag(
                        gkfs::filemap::OpenFile_flags::cloexec,
                        (arg & FD_CLOEXEC));
                return 0;

            case F_GETLK:
                LOG(DEBUG, "[GKFS] F_GETLK {}", fd);
                DEBUG_INFO("[GKFS] F_GETLK {}", fd);
                return 0;

            case F_SETLK:
                LOG(DEBUG, "[GKFS] F_SETLK {}", fd);
                DEBUG_INFO("[GKFS] F_SETLK {}", fd);
                return 0;

            default:
@@ -1224,7 +1231,7 @@ realpath(const char* path, char* resolved_path) {
                return nullptr;

            case gkfs::preload::RelativizeStatus::internal:
                LOG(DEBUG, "[GKFS] {} --> {}", resolved, path);
                DEBUG_INFO("[GKFS] {} --> {}", resolved, path);
                if(resolved_path == nullptr) {
                    resolved_path =
                            static_cast<char*>(malloc(resolved.size() + 1));
@@ -1289,7 +1296,7 @@ opendir(const char* dirname) {
        std::string resolved;
        if(resolve_gkfs_path(AT_FDCWD, dirname, resolved) ==
           PathStatus::Internal) {
            LOG(DEBUG, "[GKFS] {}", resolved);
            DEBUG_INFO("[GKFS] {}", resolved);
            return gekko_opendir(resolved);
        }
    }
@@ -1303,7 +1310,7 @@ opendir64(const char* dirname) {
        std::string resolved;
        if(resolve_gkfs_path(AT_FDCWD, dirname, resolved) ==
           PathStatus::Internal) {
            LOG(DEBUG, "[GKFS] {}", resolved);
            DEBUG_INFO("[GKFS] {}", resolved);
            return gekko_opendir(resolved);
        }
    }
@@ -1427,7 +1434,7 @@ closedir(DIR* dirp) {
    initializeGekko();
    if(CTX->interception_enabled()) {
        if(CTX->file_map()->exist(dirp->fd)) {
            LOG(DEBUG, "[GKFS] {}", dirp->fd);
            DEBUG_INFO("[GKFS] {}", dirp->fd);
            ret = gkfs::syscall::gkfs_close(dirp->fd);
            free(dirp->path);
            free(dirp);
@@ -1446,7 +1453,7 @@ telldir(DIR* dirp) {
    initializeGekko();
    if(CTX->interception_enabled()) {
        if(CTX->file_map()->exist(dirp->fd)) {
            LOG(DEBUG, "[GKFS] NOT IMPLEMENTED");
            DEBUG_INFO("[GKFS] NOT IMPLEMENTED");
            ret = 0;
            // ret = gkfs::syscall::gkfs_telldir(dirp->fd);
            return ret;
@@ -1463,7 +1470,7 @@ seekdir(DIR* dirp, long loc) {
    initializeGekko();
    if(CTX->interception_enabled()) {
        if(CTX->file_map()->exist(dirp->fd)) {
            LOG(DEBUG, "[GKFS] NOT IMPLEMENTED");
            DEBUG_INFO("[GKFS] NOT IMPLEMENTED");
            return;
        }
    }
@@ -1519,7 +1526,7 @@ fopen(const char* path, const char* mode) {
                flags = O_WRONLY | O_CREAT | O_APPEND;
            if(strchr(mode, '+'))
                flags = O_RDWR | O_CREAT;
            LOG(DEBUG, "[GEKKO] {}", resolved);
            DEBUG_INFO("[GEKKO] {}", resolved);
            const int fd = gkfs::syscall::gkfs_open(resolved, 0666, flags);
            if(fd < 0)
                return nullptr;
@@ -1547,7 +1554,7 @@ freopen64(const char* path, const char* mode, FILE* stream) {
                flags = O_WRONLY | O_CREAT | O_APPEND;
            if(strchr(mode, '+'))
                flags = O_RDWR | O_CREAT;
            LOG(DEBUG, "[GEKKO] {}", resolved);
            DEBUG_INFO("[GEKKO] {}", resolved);
            const int fd = gkfs::syscall::gkfs_open(resolved, 0666, flags);
            if(fd < 0)
                return nullptr;
@@ -1563,7 +1570,7 @@ freopen64(const char* path, const char* mode, FILE* stream) {
size_t
fread(void* ptr, size_t size, size_t nmemb, FILE* stream) {
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        LOG(DEBUG, "[GEKKO] {}", stream->_fileno);
        DEBUG_INFO("[GEKKO] {}", stream->_fileno);
        return gkfs::syscall::gkfs_read(stream->_fileno, ptr, size * nmemb) /
               size;
    }
@@ -1576,7 +1583,7 @@ fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream) {

    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        LOG(DEBUG, "[GEKKO] {}", stream->_fileno);
        DEBUG_INFO("[GEKKO] {}", stream->_fileno);
        return gkfs::syscall::gkfs_write(stream->_fileno, ptr, size * nmemb) /
               size;
    }
@@ -1588,7 +1595,7 @@ int
fseek(FILE* stream, long int offset, int whence) {
    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        LOG(DEBUG, "[GKFS] {}", stream->_fileno);
        DEBUG_INFO("[GKFS] {}", stream->_fileno);
        return gkfs::syscall::gkfs_lseek(stream->_fileno, offset, whence);
    }

@@ -1599,7 +1606,7 @@ long
ftell(FILE* stream) {
    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        LOG(DEBUG, "[GKFS] {}", stream->_fileno);
        DEBUG_INFO("[GKFS] {}", stream->_fileno);
        return gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_CUR);
    }

@@ -1610,7 +1617,7 @@ void
rewind(FILE* stream) {
    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        LOG(DEBUG, "[GKFS] {}", stream->_fileno);
        DEBUG_INFO("[GKFS] {}", stream->_fileno);
        gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_SET);
    }
    GKFS_FALLBACK(rewind, stream)
@@ -1621,7 +1628,7 @@ fclose(FILE* stream) {

    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        LOG(DEBUG, "[GKFS] {}", stream->_fileno);
        DEBUG_INFO("[GKFS] {}", stream->_fileno);
        auto ret = gkfs::syscall::gkfs_close(stream->_fileno);
        // should I do a fclose (stream)?
        free(stream);
@@ -1636,7 +1643,7 @@ int
feof(FILE* stream) {
    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        LOG(DEBUG, "[GKFS] {}", stream->_fileno);
        DEBUG_INFO("[GKFS] {}", stream->_fileno);
        off_t cur = gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_CUR);
        off_t end = gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_END);
        gkfs::syscall::gkfs_lseek(stream->_fileno, cur, SEEK_SET);
@@ -1658,7 +1665,7 @@ fgets(char* str, int n, FILE* stream) {
    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        // read str n chars
        LOG(DEBUG, "[GKFS] {}", stream->_fileno);
        DEBUG_INFO("[GKFS] {}", stream->_fileno);
        auto l = gkfs::syscall::gkfs_read(stream->_fileno, str, n);
        if(l == 0) {
            return NULL;
@@ -1678,3 +1685,68 @@ fflush(FILE* stream) {
    }
    GKFS_FALLBACK(fflush, stream)
}


void*
mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) {
    initializeGekko();
    if(is_gkfs_fd(fd)) {
        DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path());
        // create a malloc of length
        void* ptr = malloc(length);
        if(ptr == nullptr) {
            return MAP_FAILED;
        }
        // store info on mmap_set
        mmap_set.insert(std::make_tuple(ptr, fd, length, offset));
        gkfs::syscall::gkfs_pread(fd, ptr, length, offset);
        return ptr;
    }

    GKFS_FALLBACK(mmap, addr, length, prot, flags, fd, offset);
}

// implement msync, if addr is from gekkofs (we should have a set with them)
// We pwrite length to the original offset (also from the set), and return
// if not just go to the normal msync

int
msync(void* addr, size_t length, int flags) {
    initializeGekko();
    // check if addr is from gekkofs (mmap_set)
    // if so, get the fd and offset
    // pwrite length to the original offset
    // return
    // if not just go to the normal msync
    for(const auto& tuple : mmap_set) {
        if(std::get<0>(tuple) == addr) {
            int fd = std::get<1>(tuple);
            off_t offset = std::get<3>(tuple);
            gkfs::syscall::gkfs_pwrite(fd, addr, length, offset);
            return 0;
        }
    }


    GKFS_FALLBACK(msync, addr, length, flags);
}

// implement munmap, if it's on the set, call msync, free memory
int
munmap(void* addr, size_t length) {
    initializeGekko();
    // check if addr is from gekkofs (mmap_set)
    // if so, call msync
    // free memory
    // return
    // if not just go to the normal munmap
    for(auto it = mmap_set.begin(); it != mmap_set.end(); ++it) {
        if(std::get<0>(*it) == addr) {
            msync(addr, length, 0);
            free(addr);
            mmap_set.erase(it);
            return 0;
        }
    }
    GKFS_FALLBACK(munmap, addr, length);
}