diff options
author | Haibo Xu <haibo.xu@arm.com> | 2020-03-11 09:55:07 +0000 |
---|---|---|
committer | Haibo Xu <haibo.xu@arm.com> | 2020-03-18 09:27:19 +0000 |
commit | 9c35d7eb1f96f12207f78b94722f0e8b778b5af3 (patch) | |
tree | 973d75c7e8f070cc4b565b7056294811e48a7b8d /test/syscalls/linux | |
parent | eddd6ce514e3bbcc08ce9d8435c7dac12715989c (diff) |
Enable syscall sysret_test on arm64.
Fixes #2058
Signed-off-by: Haibo Xu <haibo.xu@arm.com>
Change-Id: I05750d238a6425d3a47fae15720901f4dd924a32
Diffstat (limited to 'test/syscalls/linux')
-rw-r--r-- | test/syscalls/linux/BUILD | 5 | ||||
-rw-r--r-- | test/syscalls/linux/sysret.cc | 32 |
2 files changed, 30 insertions, 7 deletions
diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 636e5db12..d0c431234 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -3336,10 +3336,7 @@ cc_binary( cc_binary( name = "sysret_test", testonly = 1, - srcs = select_arch( - amd64 = ["sysret.cc"], - arm64 = [], - ), + srcs = ["sysret.cc"], linkstatic = 1, deps = [ gtest, diff --git a/test/syscalls/linux/sysret.cc b/test/syscalls/linux/sysret.cc index 819fa655a..569190a59 100644 --- a/test/syscalls/linux/sysret.cc +++ b/test/syscalls/linux/sysret.cc @@ -14,6 +14,8 @@ // Tests to verify that the behavior of linux and gvisor matches when // 'sysret' returns to bad (aka non-canonical) %rip or %rsp. + +#include <linux/elf.h> #include <sys/ptrace.h> #include <sys/user.h> @@ -32,6 +34,7 @@ constexpr uint64_t kNonCanonicalRsp = 0xFFFF000000000000; class SysretTest : public ::testing::Test { protected: struct user_regs_struct regs_; + struct iovec iov; pid_t child_; void SetUp() override { @@ -48,10 +51,14 @@ class SysretTest : public ::testing::Test { // Parent. int status; + memset(&iov, 0, sizeof(iov)); ASSERT_THAT(pid, SyscallSucceeds()); // Might still be < 0. ASSERT_THAT(waitpid(pid, &status, 0), SyscallSucceedsWithValue(pid)); EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP); - ASSERT_THAT(ptrace(PTRACE_GETREGS, pid, 0, ®s_), SyscallSucceeds()); + + iov.iov_base = ®s_; + iov.iov_len = sizeof(regs_); + ASSERT_THAT(ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov), SyscallSucceeds()); child_ = pid; } @@ -61,13 +68,25 @@ class SysretTest : public ::testing::Test { } void SetRip(uint64_t newrip) { +#if defined(__x86_64__) regs_.rip = newrip; - ASSERT_THAT(ptrace(PTRACE_SETREGS, child_, 0, ®s_), SyscallSucceeds()); +#elif defined(__aarch64__) + regs_.pc = newrip; +#else +#error "Unknown architecture" +#endif + ASSERT_THAT(ptrace(PTRACE_SETREGSET, child_, NT_PRSTATUS, &iov), SyscallSucceeds()); } void SetRsp(uint64_t newrsp) { +#if defined(__x86_64__) regs_.rsp = newrsp; - ASSERT_THAT(ptrace(PTRACE_SETREGS, child_, 0, ®s_), SyscallSucceeds()); +#elif defined(__aarch64__) + regs_.sp = newrsp; +#else +#error "Unknown architecture" +#endif + ASSERT_THAT(ptrace(PTRACE_SETREGSET, child_, NT_PRSTATUS, &iov), SyscallSucceeds()); } // Wait waits for the child pid and returns the exit status. @@ -104,8 +123,15 @@ TEST_F(SysretTest, BadRsp) { SetRsp(kNonCanonicalRsp); Detach(); int status = Wait(); +#if defined(__x86_64__) EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGBUS) << "status = " << status; +#elif defined(__aarch64__) + EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV) + << "status = " << status; +#else +#error "Unknown architecture" +#endif } } // namespace |