summaryrefslogtreecommitdiffhomepage
path: root/vdso
diff options
context:
space:
mode:
Diffstat (limited to 'vdso')
-rw-r--r--vdso/BUILD92
-rw-r--r--vdso/barrier.h49
-rw-r--r--vdso/check_vdso.py204
-rw-r--r--vdso/compiler.h29
-rw-r--r--vdso/cycle_clock.h51
-rw-r--r--vdso/seqlock.h39
-rw-r--r--vdso/syscalls.h99
-rw-r--r--vdso/vdso.cc151
-rw-r--r--vdso/vdso_amd64.lds101
-rw-r--r--vdso/vdso_arm64.lds99
-rw-r--r--vdso/vdso_time.cc159
-rw-r--r--vdso/vdso_time.h27
12 files changed, 0 insertions, 1100 deletions
diff --git a/vdso/BUILD b/vdso/BUILD
deleted file mode 100644
index 7ceed349e..000000000
--- a/vdso/BUILD
+++ /dev/null
@@ -1,92 +0,0 @@
-# Description:
-# This VDSO is a shared library that provides the same interfaces as the
-# normal system VDSO (time, gettimeofday, clock_gettimeofday) but which uses
-# timekeeping parameters managed by the sandbox kernel.
-
-load("@bazel_tools//tools/cpp:cc_flags_supplier.bzl", "cc_flags_supplier")
-
-package(licenses = ["notice"])
-
-config_setting(
- name = "x86_64",
- constraint_values = ["@bazel_tools//platforms:x86_64"],
-)
-
-config_setting(
- name = "aarch64",
- constraint_values = ["@bazel_tools//platforms:aarch64"],
-)
-
-genrule(
- name = "vdso",
- srcs = [
- "barrier.h",
- "compiler.h",
- "cycle_clock.h",
- "seqlock.h",
- "syscalls.h",
- "vdso.cc",
- "vdso_amd64.lds",
- "vdso_arm64.lds",
- "vdso_time.h",
- "vdso_time.cc",
- ],
- outs = [
- "vdso.so",
- ],
- cmd = "$(CC) $(CC_FLAGS) " +
- "-I. " +
- "-O2 " +
- "-std=c++11 " +
- "-fPIC " +
- # Some toolchains enable stack protector by default. Disable it, the
- # VDSO has no hooks to handle failures.
- "-fno-stack-protector " +
- "-fuse-ld=gold " +
- select({
- ":x86_64": "-m64 ",
- "//conditions:default": "",
- }) +
- "-shared " +
- "-nostdlib " +
- "-Wl,-soname=linux-vdso.so.1 " +
- "-Wl,--hash-style=sysv " +
- "-Wl,--no-undefined " +
- "-Wl,-Bsymbolic " +
- "-Wl,-z,max-page-size=4096 " +
- "-Wl,-z,common-page-size=4096 " +
- select(
- {
- ":x86_64": "-Wl,-T$(location vdso_amd64.lds) ",
- ":aarch64": "-Wl,-T$(location vdso_arm64.lds) ",
- },
- no_match_error = "Unsupported architecture",
- ) +
- "-o $(location vdso.so) " +
- "$(location vdso.cc) " +
- "$(location vdso_time.cc) " +
- "&& $(location :check_vdso) " +
- "--check-data " +
- "--vdso $(location vdso.so) ",
- features = ["-pie"],
- toolchains = [
- "@bazel_tools//tools/cpp:current_cc_toolchain",
- ":no_pie_cc_flags",
- ],
- tools = [
- ":check_vdso",
- ],
- visibility = ["//:sandbox"],
-)
-
-cc_flags_supplier(
- name = "no_pie_cc_flags",
- features = ["-pie"],
-)
-
-py_binary(
- name = "check_vdso",
- srcs = ["check_vdso.py"],
- python_version = "PY2",
- visibility = ["//:sandbox"],
-)
diff --git a/vdso/barrier.h b/vdso/barrier.h
deleted file mode 100644
index edba4afb5..000000000
--- a/vdso/barrier.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef VDSO_BARRIER_H_
-#define VDSO_BARRIER_H_
-
-namespace vdso {
-
-// Compiler Optimization barrier.
-inline void barrier(void) { __asm__ __volatile__("" ::: "memory"); }
-
-#if __x86_64__
-
-inline void memory_barrier(void) {
- __asm__ __volatile__("mfence" ::: "memory");
-}
-inline void read_barrier(void) { barrier(); }
-inline void write_barrier(void) { barrier(); }
-
-#elif __aarch64__
-
-inline void memory_barrier(void) {
- __asm__ __volatile__("dmb ish" ::: "memory");
-}
-inline void read_barrier(void) {
- __asm__ __volatile__("dmb ishld" ::: "memory");
-}
-inline void write_barrier(void) {
- __asm__ __volatile__("dmb ishst" ::: "memory");
-}
-
-#else
-#error "unsupported architecture"
-#endif
-
-} // namespace vdso
-
-#endif // VDSO_BARRIER_H_
diff --git a/vdso/check_vdso.py b/vdso/check_vdso.py
deleted file mode 100644
index b3ee574f3..000000000
--- a/vdso/check_vdso.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# Copyright 2018 The gVisor Authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Verify VDSO ELF does not contain any relocations and is directly mmappable.
-"""
-
-import argparse
-import logging
-import re
-import subprocess
-
-PAGE_SIZE = 4096
-
-
-def PageRoundDown(addr):
- """Rounds down to the nearest page.
-
- Args:
- addr: An address.
-
- Returns:
- The address rounded down to the nearest page.
- """
- return addr & ~(PAGE_SIZE - 1)
-
-
-def Fatal(*args, **kwargs):
- """Logs a critical message and exits with code 1.
-
- Args:
- *args: Args to pass to logging.critical.
- **kwargs: Keyword args to pass to logging.critical.
- """
- logging.critical(*args, **kwargs)
- exit(1)
-
-
-def CheckSegments(vdso_path):
- """Verifies layout of PT_LOAD segments.
-
- PT_LOAD segments must be laid out such that the ELF is directly mmappable.
-
- Specifically, check that:
- * PT_LOAD file offsets are equivalent to the memory offset from the first
- segment.
- * No extra zeroed space (memsz) is required.
- * PT_LOAD segments are in order (required for any ELF).
- * No two PT_LOAD segments share part of the same page.
-
- The readelf line format looks like:
- Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
- LOAD 0x000000 0xffffffffff700000 0xffffffffff700000 0x000e68 0x000e68 R E 0x1000
-
- Args:
- vdso_path: Path to VDSO binary.
- """
- output = subprocess.check_output(["readelf", "-lW", vdso_path]).decode()
- lines = output.split("\n")
-
- segments = []
- for line in lines:
- if not line.startswith(" LOAD"):
- continue
-
- components = line.split()
-
- segments.append({
- "offset": int(components[1], 16),
- "addr": int(components[2], 16),
- "filesz": int(components[4], 16),
- "memsz": int(components[5], 16),
- })
-
- if not segments:
- Fatal("No PT_LOAD segments in VDSO")
-
- first = segments[0]
- if first["offset"] != 0:
- Fatal("First PT_LOAD segment has non-zero file offset: %s", first)
-
- for i, segment in enumerate(segments):
- memoff = segment["addr"] - first["addr"]
- if memoff != segment["offset"]:
- Fatal("PT_LOAD segment has different memory and file offsets: %s",
- segments)
-
- if segment["memsz"] != segment["filesz"]:
- Fatal("PT_LOAD segment memsz != filesz: %s", segment)
-
- if i > 0:
- last_end = segments[i-1]["addr"] + segments[i-1]["memsz"]
- if segment["addr"] < last_end:
- Fatal("PT_LOAD segments out of order")
-
- last_page = PageRoundDown(last_end)
- start_page = PageRoundDown(segment["addr"])
- if last_page >= start_page:
- Fatal("PT_LOAD segments share a page: %s and %s", segment,
- segments[i - 1])
-
-
-# Matches the section name in readelf -SW output.
-_SECTION_NAME_RE = re.compile(r"""^\s+\[\ ?\d+\]\s+
- (?P<name>\.\S+)\s+
- (?P<type>\S+)\s+
- (?P<addr>[0-9a-f]+)\s+
- (?P<off>[0-9a-f]+)\s+
- (?P<size>[0-9a-f]+)""", re.VERBOSE)
-
-
-def CheckData(vdso_path):
- """Verifies the VDSO contains no .data or .bss sections.
-
- The readelf line format looks like:
-
- There are 15 section headers, starting at offset 0x15f0:
-
- Section Headers:
- [Nr] Name Type Address Off Size ES Flg Lk Inf Al
- [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
- [ 1] .hash HASH ffffffffff700120 000120 000040 04 A 2 0 8
- [ 2] .dynsym DYNSYM ffffffffff700160 000160 000108 18 A 3 1 8
- ...
- [13] .strtab STRTAB 0000000000000000 001448 000123 00 0 0 1
- [14] .shstrtab STRTAB 0000000000000000 00156b 000083 00 0 0 1
- Key to Flags:
- W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
- L (link order), O (extra OS processing required), G (group), T (TLS),
- C (compressed), x (unknown), o (OS specific), E (exclude),
- l (large), p (processor specific)
-
- Args:
- vdso_path: Path to VDSO binary.
- """
- output = subprocess.check_output(["readelf", "-SW", vdso_path]).decode()
- lines = output.split("\n")
-
- found_text = False
- for line in lines:
- m = re.search(_SECTION_NAME_RE, line)
- if not m:
- continue
-
- if not line.startswith(" ["):
- continue
-
- name = m.group("name")
- size = int(m.group("size"), 16)
-
- if name == ".text" and size != 0:
- found_text = True
-
- # Clang will typically omit these sections entirely; gcc will include them
- # but with size 0.
- if name.startswith(".data") and size != 0:
- Fatal("VDSO contains non-empty .data section:\n%s" % output)
-
- if name.startswith(".bss") and size != 0:
- Fatal("VDSO contains non-empty .bss section:\n%s" % output)
-
- if not found_text:
- Fatal("VDSO contains no/empty .text section? Bad parsing?:\n%s" % output)
-
-
-def CheckRelocs(vdso_path):
- """Verifies that the VDSO includes no relocations.
-
- Args:
- vdso_path: Path to VDSO binary.
- """
- output = subprocess.check_output(["readelf", "-r", vdso_path]).decode()
- if output.strip() != "There are no relocations in this file.":
- Fatal("VDSO contains relocations: %s", output)
-
-
-def main():
- parser = argparse.ArgumentParser(description="Verify VDSO ELF.")
- parser.add_argument("--vdso", required=True, help="Path to VDSO ELF")
- parser.add_argument(
- "--check-data",
- action="store_true",
- help="Check that the ELF contains no .data or .bss sections")
- args = parser.parse_args()
-
- CheckSegments(args.vdso)
- CheckRelocs(args.vdso)
-
- if args.check_data:
- CheckData(args.vdso)
-
-
-if __name__ == "__main__":
- main()
diff --git a/vdso/compiler.h b/vdso/compiler.h
deleted file mode 100644
index 54a510000..000000000
--- a/vdso/compiler.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef VDSO_COMPILER_H_
-#define VDSO_COMPILER_H_
-
-#define likely(x) __builtin_expect(!!(x), 1)
-#define unlikely(x) __builtin_expect(!!(x), 0)
-
-#ifndef __section
-#define __section(S) __attribute__((__section__(#S)))
-#endif
-
-#ifndef __aligned
-#define __aligned(N) __attribute__((__aligned__(N)))
-#endif
-
-#endif // VDSO_COMPILER_H_
diff --git a/vdso/cycle_clock.h b/vdso/cycle_clock.h
deleted file mode 100644
index 5d3fbb257..000000000
--- a/vdso/cycle_clock.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef VDSO_CYCLE_CLOCK_H_
-#define VDSO_CYCLE_CLOCK_H_
-
-#include <stdint.h>
-
-#include "vdso/barrier.h"
-
-namespace vdso {
-
-#if __x86_64__
-
-// TODO(b/74613497): The appropriate barrier instruction to use with rdtsc on
-// x86_64 depends on the vendor. Intel processors can use lfence but AMD may
-// need mfence, depending on MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT.
-
-static inline uint64_t cycle_clock(void) {
- uint32_t lo, hi;
- asm volatile("lfence" : : : "memory");
- asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
- return ((uint64_t)hi << 32) | lo;
-}
-
-#elif __aarch64__
-
-static inline uint64_t cycle_clock(void) {
- uint64_t val;
- asm volatile("mrs %0, CNTVCT_EL0" : "=r"(val)::"memory");
- return val;
-}
-
-#else
-#error "unsupported architecture"
-#endif
-
-} // namespace vdso
-
-#endif // VDSO_CYCLE_CLOCK_H_
diff --git a/vdso/seqlock.h b/vdso/seqlock.h
deleted file mode 100644
index 7a173174b..000000000
--- a/vdso/seqlock.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Low level raw interfaces to the sequence counter used by the VDSO.
-#ifndef VDSO_SEQLOCK_H_
-#define VDSO_SEQLOCK_H_
-
-#include <stdint.h>
-
-#include "vdso/barrier.h"
-#include "vdso/compiler.h"
-
-namespace vdso {
-
-inline int32_t read_seqcount_begin(const uint64_t* s) {
- uint64_t seq = *s;
- read_barrier();
- return seq & ~1;
-}
-
-inline int read_seqcount_retry(const uint64_t* s, uint64_t seq) {
- read_barrier();
- return unlikely(*s != seq);
-}
-
-} // namespace vdso
-
-#endif // VDSO_SEQLOCK_H_
diff --git a/vdso/syscalls.h b/vdso/syscalls.h
deleted file mode 100644
index f5865bb72..000000000
--- a/vdso/syscalls.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// System call support for the VDSO.
-//
-// Provides fallback system call interfaces for getcpu()
-// and clock_gettime().
-
-#ifndef VDSO_SYSCALLS_H_
-#define VDSO_SYSCALLS_H_
-
-#include <asm/unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <sys/types.h>
-
-namespace vdso {
-
-#if __x86_64__
-
-struct getcpu_cache;
-
-static inline int sys_clock_gettime(clockid_t clock, struct timespec* ts) {
- int num = __NR_clock_gettime;
- asm volatile("syscall\n"
- : "+a"(num)
- : "D"(clock), "S"(ts)
- : "rcx", "r11", "memory");
- return num;
-}
-
-static inline int sys_getcpu(unsigned* cpu, unsigned* node,
- struct getcpu_cache* cache) {
- int num = __NR_getcpu;
- asm volatile("syscall\n"
- : "+a"(num)
- : "D"(cpu), "S"(node), "d"(cache)
- : "rcx", "r11", "memory");
- return num;
-}
-
-#elif __aarch64__
-
-static inline int sys_rt_sigreturn(void) {
- int num = __NR_rt_sigreturn;
-
- asm volatile(
- "mov x8, %0\n"
- "svc #0 \n"
- : "+r"(num)
- :
- :);
- return num;
-}
-
-static inline int sys_clock_gettime(clockid_t _clkid, struct timespec *_ts) {
- register struct timespec *ts asm("x1") = _ts;
- register clockid_t clkid asm("x0") = _clkid;
- register long ret asm("x0");
- register long nr asm("x8") = __NR_clock_gettime;
-
- asm volatile("svc #0\n"
- : "=r"(ret)
- : "r"(clkid), "r"(ts), "r"(nr)
- : "memory");
- return ret;
-}
-
-static inline int sys_clock_getres(clockid_t _clkid, struct timespec *_ts) {
- register struct timespec *ts asm("x1") = _ts;
- register clockid_t clkid asm("x0") = _clkid;
- register long ret asm("x0");
- register long nr asm("x8") = __NR_clock_getres;
-
- asm volatile("svc #0\n"
- : "=r"(ret)
- : "r"(clkid), "r"(ts), "r"(nr)
- : "memory");
- return ret;
-}
-
-#else
-#error "unsupported architecture"
-#endif
-} // namespace vdso
-
-#endif // VDSO_SYSCALLS_H_
diff --git a/vdso/vdso.cc b/vdso/vdso.cc
deleted file mode 100644
index 8bb80a7a4..000000000
--- a/vdso/vdso.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// This is the VDSO for sandboxed binaries. This file just contains the entry
-// points to the VDSO. All of the real work is done in vdso_time.cc
-
-#define _DEFAULT_SOURCE // ensure glibc provides struct timezone.
-#include <sys/time.h>
-#include <time.h>
-
-#include "vdso/syscalls.h"
-#include "vdso/vdso_time.h"
-
-namespace vdso {
-namespace {
-
-int __common_clock_gettime(clockid_t clock, struct timespec* ts) {
- int ret;
-
- switch (clock) {
- case CLOCK_REALTIME:
- ret = ClockRealtime(ts);
- break;
-
- case CLOCK_BOOTTIME:
- // Fallthrough, CLOCK_BOOTTIME is an alias for CLOCK_MONOTONIC
- case CLOCK_MONOTONIC:
- ret = ClockMonotonic(ts);
- break;
-
- default:
- ret = sys_clock_gettime(clock, ts);
- break;
- }
-
- return ret;
-}
-
-int __common_gettimeofday(struct timeval* tv, struct timezone* tz) {
- if (tv) {
- struct timespec ts;
- int ret = ClockRealtime(&ts);
- if (ret) {
- return ret;
- }
- tv->tv_sec = ts.tv_sec;
- tv->tv_usec = ts.tv_nsec / 1000;
- }
-
- // Nobody should be calling gettimeofday() with a non-NULL
- // timezone pointer. If they do then they will get zeros.
- if (tz) {
- tz->tz_minuteswest = 0;
- tz->tz_dsttime = 0;
- }
-
- return 0;
-}
-} // namespace
-
-#if __x86_64__
-
-// __vdso_clock_gettime() implements clock_gettime()
-extern "C" int __vdso_clock_gettime(clockid_t clock, struct timespec* ts) {
- return __common_clock_gettime(clock, ts);
-}
-extern "C" int clock_gettime(clockid_t clock, struct timespec* ts)
- __attribute__((weak, alias("__vdso_clock_gettime")));
-
-// __vdso_gettimeofday() implements gettimeofday()
-extern "C" int __vdso_gettimeofday(struct timeval* tv, struct timezone* tz) {
- return __common_gettimeofday(tv, tz);
-}
-extern "C" int gettimeofday(struct timeval* tv, struct timezone* tz)
- __attribute__((weak, alias("__vdso_gettimeofday")));
-
-// __vdso_time() implements time()
-extern "C" time_t __vdso_time(time_t* t) {
- struct timespec ts;
- ClockRealtime(&ts);
- if (t) {
- *t = ts.tv_sec;
- }
- return ts.tv_sec;
-}
-extern "C" time_t time(time_t* t) __attribute__((weak, alias("__vdso_time")));
-
-// __vdso_getcpu() implements getcpu()
-extern "C" long __vdso_getcpu(unsigned* cpu, unsigned* node,
- struct getcpu_cache* cache) {
- // No optimizations yet, just make the real system call.
- return sys_getcpu(cpu, node, cache);
-}
-extern "C" long getcpu(unsigned* cpu, unsigned* node,
- struct getcpu_cache* cache)
- __attribute__((weak, alias("__vdso_getcpu")));
-
-#elif __aarch64__
-
-// __kernel_clock_gettime() implements clock_gettime()
-extern "C" int __kernel_clock_gettime(clockid_t clock, struct timespec* ts) {
- return __common_clock_gettime(clock, ts);
-}
-
-// __kernel_gettimeofday() implements gettimeofday()
-extern "C" int __kernel_gettimeofday(struct timeval* tv, struct timezone* tz) {
- return __common_gettimeofday(tv, tz);
-}
-
-// __kernel_clock_getres() implements clock_getres()
-extern "C" int __kernel_clock_getres(clockid_t clock, struct timespec* res) {
- int ret = 0;
-
- switch (clock) {
- case CLOCK_REALTIME:
- case CLOCK_MONOTONIC:
- case CLOCK_BOOTTIME: {
- res->tv_sec = 0;
- res->tv_nsec = 1;
- break;
- }
-
- default:
- ret = sys_clock_getres(clock, res);
- break;
- }
-
- return ret;
-}
-
-// __kernel_rt_sigreturn() implements gettimeofday()
-extern "C" int __kernel_rt_sigreturn(unsigned long unused) {
- // No optimizations yet, just make the real system call.
- return sys_rt_sigreturn();
-}
-
-#else
-#error "unsupported architecture"
-#endif
-} // namespace vdso
diff --git a/vdso/vdso_amd64.lds b/vdso/vdso_amd64.lds
deleted file mode 100644
index e2615ae9e..000000000
--- a/vdso/vdso_amd64.lds
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Linker script for the VDSO.
- *
- * The VDSO is essentially a normal ELF shared library that is mapped into the
- * address space of the process that is going to use it. The address of the
- * VDSO is passed to the runtime linker in the AT_SYSINFO_EHDR entry of the aux
- * vector.
- *
- * There are, however, three ways in which the VDSO differs from a normal
- * shared library:
- *
- * - The runtime linker does not attempt to process any relocations for the
- * VDSO so it is the responsibility of whoever loads the VDSO into the
- * address space to do this if necessary. Because of this restriction we are
- * careful to ensure that the VDSO does not need to have any relocations
- * applied to it.
- *
- * - Although the VDSO is position independent and would normally be linked at
- * virtual address 0, the Linux kernel VDSO is actually linked at a non zero
- * virtual address and the code in the system runtime linker that handles the
- * VDSO expects this to be the case so we have to explicitly link this VDSO
- * at a non zero address. The actual address is arbitrary, but we use the
- * same one as the Linux kernel VDSO.
- *
- * - The VDSO will be directly mmapped by the sentry, rather than going through
- * a normal ELF loading process. The VDSO must be carefully constructed such
- * that the layout in the ELF file is identical to the layout in memory.
- */
-
-VDSO_PRELINK = 0xffffffffff700000;
-
-SECTIONS {
- /* The parameter page is mapped just before the VDSO. */
- _params = VDSO_PRELINK - 0x1000;
-
- . = VDSO_PRELINK + SIZEOF_HEADERS;
-
- .hash : { *(.hash) } :text
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
-
- .note : { *(.note.*) } :text :note
-
- .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
- .eh_frame : { KEEP (*(.eh_frame)) } :text
-
- .dynamic : { *(.dynamic) } :text :dynamic
-
- .rodata : { *(.rodata*) } :text
-
- .altinstructions : { *(.altinstructions) }
- .altinstr_replacement : { *(.altinstr_replacement) }
-
- /*
- * TODO(gvisor.dev/issue/157): Remove this alignment? Then the VDSO would fit
- * in a single page.
- */
- . = ALIGN(0x1000);
- .text : { *(.text*) } :text =0x90909090
-
- /*
- * N.B. There is no data/bss section. This VDSO neither needs nor uses a data
- * section. We omit it entirely because some gcc/clang and gold/bfd version
- * combinations struggle to handle an empty data PHDR segment (internal
- * linker assertion failures result).
- *
- * If the VDSO does incorrectly include a data section, the linker will
- * include it in the text segment. check_vdso.py looks for this degenerate
- * case.
- */
-}
-
-PHDRS {
- text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R | PF_X */
- dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
- note PT_NOTE FLAGS(4); /* PF_R */
- eh_frame_hdr PT_GNU_EH_FRAME;
-}
-
-/*
- * Define the symbols that are to be exported.
- */
-VERSION {
- LINUX_2.6 {
- global:
- clock_gettime;
- __vdso_clock_gettime;
- gettimeofday;
- __vdso_gettimeofday;
- getcpu;
- __vdso_getcpu;
- time;
- __vdso_time;
-
- local: *;
- };
-}
diff --git a/vdso/vdso_arm64.lds b/vdso/vdso_arm64.lds
deleted file mode 100644
index 469185468..000000000
--- a/vdso/vdso_arm64.lds
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Linker script for the VDSO.
- *
- * The VDSO is essentially a normal ELF shared library that is mapped into the
- * address space of the process that is going to use it. The address of the
- * VDSO is passed to the runtime linker in the AT_SYSINFO_EHDR entry of the aux
- * vector.
- *
- * There are, however, three ways in which the VDSO differs from a normal
- * shared library:
- *
- * - The runtime linker does not attempt to process any relocations for the
- * VDSO so it is the responsibility of whoever loads the VDSO into the
- * address space to do this if necessary. Because of this restriction we are
- * careful to ensure that the VDSO does not need to have any relocations
- * applied to it.
- *
- * - Although the VDSO is position independent and would normally be linked at
- * virtual address 0, the Linux kernel VDSO is actually linked at a non zero
- * virtual address and the code in the system runtime linker that handles the
- * VDSO expects this to be the case so we have to explicitly link this VDSO
- * at a non zero address. The actual address is arbitrary, but we use the
- * same one as the Linux kernel VDSO.
- *
- * - The VDSO will be directly mmapped by the sentry, rather than going through
- * a normal ELF loading process. The VDSO must be carefully constructed such
- * that the layout in the ELF file is identical to the layout in memory.
- */
-
-VDSO_PRELINK = 0xffffffffff700000;
-
-OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", "elf64-littleaarch64")
-OUTPUT_ARCH(aarch64)
-
-SECTIONS {
- /* The parameter page is mapped just before the VDSO. */
- _params = VDSO_PRELINK - 0x1000;
-
- . = VDSO_PRELINK + SIZEOF_HEADERS;
-
- .hash : { *(.hash) } :text
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
-
- .note : { *(.note.*) } :text :note
-
- .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
- .eh_frame : { KEEP (*(.eh_frame)) } :text
-
- .dynamic : { *(.dynamic) } :text :dynamic
-
- .rodata : { *(.rodata*) } :text
-
- .altinstructions : { *(.altinstructions) }
- .altinstr_replacement : { *(.altinstr_replacement) }
-
- /*
- * TODO(gvisor.dev/issue/157): Remove this alignment? Then the VDSO would fit
- * in a single page.
- */
- . = ALIGN(0x1000);
- .text : { *(.text*) } :text =0xd503201f
-
- /*
- * N.B. There is no data/bss section. This VDSO neither needs nor uses a data
- * section. We omit it entirely because some gcc/clang and gold/bfd version
- * combinations struggle to handle an empty data PHDR segment (internal
- * linker assertion failures result).
- *
- * If the VDSO does incorrectly include a data section, the linker will
- * include it in the text segment. check_vdso.py looks for this degenerate
- * case.
- */
-}
-
-PHDRS {
- text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R | PF_X */
- dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
- note PT_NOTE FLAGS(4); /* PF_R */
- eh_frame_hdr PT_GNU_EH_FRAME;
-}
-
-/*
- * Define the symbols that are to be exported.
- */
-VERSION {
- LINUX_2.6.39 {
- global:
- __kernel_clock_getres;
- __kernel_clock_gettime;
- __kernel_gettimeofday;
- __kernel_rt_sigreturn;
- local: *;
- };
-}
diff --git a/vdso/vdso_time.cc b/vdso/vdso_time.cc
deleted file mode 100644
index 1bb4bb86b..000000000
--- a/vdso/vdso_time.cc
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "vdso/vdso_time.h"
-
-#include <stdint.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include "vdso/cycle_clock.h"
-#include "vdso/seqlock.h"
-#include "vdso/syscalls.h"
-
-// struct params defines the layout of the parameter page maintained by the
-// kernel (i.e., sentry).
-//
-// This is similar to the VVAR page maintained by the normal Linux kernel for
-// its VDSO, but it has a different layout.
-//
-// It must be kept in sync with VDSOParamPage in pkg/sentry/kernel/vdso.go.
-struct params {
- uint64_t seq_count;
-
- uint64_t monotonic_ready;
- int64_t monotonic_base_cycles;
- int64_t monotonic_base_ref;
- uint64_t monotonic_frequency;
-
- uint64_t realtime_ready;
- int64_t realtime_base_cycles;
- int64_t realtime_base_ref;
- uint64_t realtime_frequency;
-};
-
-// Returns a pointer to the global parameter page.
-//
-// This page lives in the page just before the VDSO binary itself. The linker
-// defines _params as the page before the VDSO.
-//
-// Ideally, we'd simply declare _params as an extern struct params.
-// Unfortunately various combinations of old/new versions of gcc/clang and
-// gold/bfd struggle to generate references to such a global without generating
-// relocations.
-//
-// So instead, we use inline assembly with a construct that seems to have wide
-// compatibility across many toolchains.
-#if __x86_64__
-
-inline struct params* get_params() {
- struct params* p = nullptr;
- asm("leaq _params(%%rip), %0" : "=r"(p) : :);
- return p;
-}
-
-#elif __aarch64__
-
-inline struct params* get_params() {
- struct params* p = nullptr;
- asm("adr %0, _params" : "=r"(p) : :);
- return p;
-}
-
-#else
-#error "unsupported architecture"
-#endif
-
-namespace vdso {
-
-const uint64_t kNsecsPerSec = 1000000000UL;
-
-inline struct timespec ns_to_timespec(uint64_t ns) {
- struct timespec ts;
- ts.tv_sec = ns / kNsecsPerSec;
- ts.tv_nsec = ns % kNsecsPerSec;
- return ts;
-}
-
-inline uint64_t cycles_to_ns(uint64_t frequency, uint64_t cycles) {
- uint64_t mult = (kNsecsPerSec << 32) / frequency;
- return ((unsigned __int128)cycles * mult) >> 32;
-}
-
-// ClockRealtime() is the VDSO implementation of clock_gettime(CLOCK_REALTIME).
-int ClockRealtime(struct timespec* ts) {
- struct params* params = get_params();
- uint64_t seq;
- uint64_t ready;
- int64_t base_ref;
- int64_t base_cycles;
- uint64_t frequency;
- int64_t now_cycles;
-
- do {
- seq = read_seqcount_begin(&params->seq_count);
- ready = params->realtime_ready;
- base_ref = params->realtime_base_ref;
- base_cycles = params->realtime_base_cycles;
- frequency = params->realtime_frequency;
- now_cycles = cycle_clock();
- } while (read_seqcount_retry(&params->seq_count, seq));
-
- if (!ready) {
- // The sandbox kernel ensures that we won't compute a time later than this
- // once the params are ready.
- return sys_clock_gettime(CLOCK_REALTIME, ts);
- }
-
- int64_t delta_cycles =
- (now_cycles < base_cycles) ? 0 : now_cycles - base_cycles;
- int64_t now_ns = base_ref + cycles_to_ns(frequency, delta_cycles);
- *ts = ns_to_timespec(now_ns);
- return 0;
-}
-
-// ClockMonotonic() is the VDSO implementation of
-// clock_gettime(CLOCK_MONOTONIC).
-int ClockMonotonic(struct timespec* ts) {
- struct params* params = get_params();
- uint64_t seq;
- uint64_t ready;
- int64_t base_ref;
- int64_t base_cycles;
- uint64_t frequency;
- int64_t now_cycles;
-
- do {
- seq = read_seqcount_begin(&params->seq_count);
- ready = params->monotonic_ready;
- base_ref = params->monotonic_base_ref;
- base_cycles = params->monotonic_base_cycles;
- frequency = params->monotonic_frequency;
- now_cycles = cycle_clock();
- } while (read_seqcount_retry(&params->seq_count, seq));
-
- if (!ready) {
- // The sandbox kernel ensures that we won't compute a time later than this
- // once the params are ready.
- return sys_clock_gettime(CLOCK_MONOTONIC, ts);
- }
-
- int64_t delta_cycles =
- (now_cycles < base_cycles) ? 0 : now_cycles - base_cycles;
- int64_t now_ns = base_ref + cycles_to_ns(frequency, delta_cycles);
- *ts = ns_to_timespec(now_ns);
- return 0;
-}
-
-} // namespace vdso
diff --git a/vdso/vdso_time.h b/vdso/vdso_time.h
deleted file mode 100644
index 70d079efc..000000000
--- a/vdso/vdso_time.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef VDSO_VDSO_TIME_H_
-#define VDSO_VDSO_TIME_H_
-
-#include <time.h>
-
-namespace vdso {
-
-int ClockRealtime(struct timespec* ts);
-int ClockMonotonic(struct timespec* ts);
-
-} // namespace vdso
-
-#endif // VDSO_VDSO_TIME_H_