From e64e82e86cf233cce8a5b391644241ca16ea06f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Thu, 5 Nov 2015 18:43:40 +0100 Subject: [PATCH] Add support for readlinkat syscall --- CMakeLists.txt | 1 + src/record_syscall.cc | 7 +++++++ src/syscalls.py | 2 +- src/test/readlinkat.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/test/readlinkat.c diff --git a/CMakeLists.txt b/CMakeLists.txt index a251900ca7e..59b2b85021b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -421,6 +421,7 @@ set(BASIC_TESTS read_nothing readdir readlink + readlinkat readv rlimit robust_futex diff --git a/src/record_syscall.cc b/src/record_syscall.cc index e78850e50a5..9fe2eb070ca 100644 --- a/src/record_syscall.cc +++ b/src/record_syscall.cc @@ -2036,6 +2036,13 @@ static Switchable rec_prepare_syscall_arch(Task* t, return PREVENT_SWITCH; } + case Arch::readlinkat: { + syscall_state.reg_parameter( + 3, ParamSize::from_syscall_result( + (size_t)t->regs().arg4())); + return PREVENT_SWITCH; + } + case Arch::getgroups: { // We could record a little less data by restricting the recorded data // to the syscall result * sizeof(Arch::legacy_gid_t), but that would diff --git a/src/syscalls.py b/src/syscalls.py index c761c72e2e2..5cc639ddc00 100644 --- a/src/syscalls.py +++ b/src/syscalls.py @@ -1420,7 +1420,7 @@ def __init__(self, **kwargs): renameat = UnsupportedSyscall(x86=302, x64=264) linkat = UnsupportedSyscall(x86=303, x64=265) symlinkat = UnsupportedSyscall(x86=304, x64=266) -readlinkat = UnsupportedSyscall(x86=305, x64=267) +readlinkat = IrregularEmulatedSyscall(x86=305, x64=267) fchmodat = UnsupportedSyscall(x86=306, x64=268) # int faccessat(int dirfd, const char *pathname, int mode, int flags) diff --git a/src/test/readlinkat.c b/src/test/readlinkat.c new file mode 100644 index 00000000000..18b4683d513 --- /dev/null +++ b/src/test/readlinkat.c @@ -0,0 +1,42 @@ +/* -*- Mode: C; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */ + +#include "rrutil.h" + +#define BUF_SIZE 10 +#define BUF2_SIZE 1000 + +int main(int argc, char* argv[]) { + char path[] = "rr-test-file-XXXXXX"; + char dpath[] = "rr-test-dir-XXXXXX"; + const char *dir_path = mkdtemp(dpath); + int count; + char link[PATH_MAX]; + char* buf = allocate_guard(BUF_SIZE, 'q'); + char* buf2 = allocate_guard(BUF2_SIZE, 'r'); + + test_assert(0 <= dirfd); + + chdir(dir_path); + + for (count = 0;; ++count) { + sprintf(link, "rr-test-link-%d", count); + int ret = symlink(path, link); + if (ret == 0) { + break; + } + test_assert(errno == EEXIST); + } + int ret = readlinkat(AT_FDCWD, link, buf, BUF_SIZE); + test_assert(BUF_SIZE == ret); + test_assert(0 == memcmp(path, buf, BUF_SIZE)); + verify_guard(BUF_SIZE, buf); + + test_assert(strlen(path) == readlinkat(AT_FDCWD, link, buf2, BUF2_SIZE)); + test_assert(0 == memcmp(path, buf2, strlen(path))); + verify_guard(BUF2_SIZE, buf2); + + test_assert(0 == unlink(link)); + + atomic_puts("EXIT-SUCCESS"); + return 0; +}