Add clock_gettimeofday

This commit is contained in:
Tate, Hongliang Tian 2019-07-12 12:10:33 +00:00
parent c096e7d0b9
commit e1e46c9935
8 changed files with 163 additions and 38 deletions

@ -17,7 +17,8 @@ enclave {
untrusted {
void ocall_print_string([in, string] const char* msg);
int ocall_run_new_task(void);
void ocall_gettimeofday([out] long* seconds, [out] long* microseconds);
void ocall_gettimeofday([out] long* sec, [out] long* us);
void ocall_clock_gettime(int clockid, [out] long* sec, [out] long* ns);
void ocall_sync(void);
};
};

@ -13,7 +13,7 @@ use prelude::*;
use process::{pid_t, ChildProcessFilter, CloneFlags, FileAction, FutexFlags, FutexOp};
use std::ffi::{CStr, CString};
use std::ptr;
use time::timeval_t;
use time::{timeval_t, clockid_t, timespec_t};
use util::mem_util::from_user::*;
use vm::{VMPerms, MMapFlags};
use {fs, process, std, vm};
@ -203,6 +203,7 @@ pub extern "C" fn dispatch_syscall(
SYS_DUP3 => do_dup3(arg0 as FileDesc, arg1 as FileDesc, arg2 as u32),
SYS_GETTIMEOFDAY => do_gettimeofday(arg0 as *mut timeval_t),
SYS_CLOCK_GETTIME => do_clock_gettime(arg0 as clockid_t, arg1 as *mut timespec_t),
SYS_UNAME => do_uname(arg0 as *mut utsname_t),
@ -790,6 +791,17 @@ fn do_gettimeofday(tv_u: *mut timeval_t) -> Result<isize, Error> {
Ok(0)
}
fn do_clock_gettime(clockid: clockid_t, ts_u: *mut timespec_t) -> Result<isize, Error> {
check_mut_ptr(ts_u)?;
let clockid = time::ClockID::from_raw(clockid)?;
let ts = time::do_clock_gettime(clockid)?;
unsafe {
*ts_u = ts;
}
Ok(0)
}
// FIXME: use this
const MAP_FAILED: *const c_void = ((-1) as i64) as *const c_void;

@ -11,6 +11,7 @@ pub type suseconds_t = i64;
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
#[allow(non_camel_case_types)]
pub struct timeval_t {
sec: time_t,
usec: suseconds_t,
@ -34,6 +35,64 @@ extern "C" {
fn ocall_gettimeofday(sec: *mut time_t, usec: *mut suseconds_t) -> sgx_status_t;
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
#[allow(non_camel_case_types)]
pub struct timespec_t {
sec: time_t,
nsec: i64,
}
#[allow(non_camel_case_types)]
pub type clockid_t = i32;
#[derive(Debug, Copy, Clone)]
#[allow(non_camel_case_types)]
pub enum ClockID {
CLOCK_REALTIME = 0,
CLOCK_MONOTONIC = 1,
CLOCK_PROCESS_CPUTIME_ID = 2,
CLOCK_THREAD_CPUTIME_ID = 3,
CLOCK_MONOTONIC_RAW = 4,
CLOCK_REALTIME_COARSE = 5,
CLOCK_MONOTONIC_COARSE = 6,
CLOCK_BOOTTIME = 7,
}
impl ClockID {
#[deny(unreachable_patterns)]
pub fn from_raw(clockid: clockid_t) -> Result<ClockID, Error> {
Ok(match clockid as i32 {
0 => ClockID::CLOCK_REALTIME,
1 => ClockID::CLOCK_MONOTONIC,
2 => ClockID::CLOCK_PROCESS_CPUTIME_ID,
3 => ClockID::CLOCK_THREAD_CPUTIME_ID,
4 => ClockID::CLOCK_MONOTONIC_RAW,
5 => ClockID::CLOCK_REALTIME_COARSE,
6 => ClockID::CLOCK_MONOTONIC_COARSE,
7 => ClockID::CLOCK_BOOTTIME,
_ => return errno!(EINVAL, "invalid command"),
})
}
}
pub fn do_clock_gettime(clockid: ClockID) -> Result<timespec_t, Error> {
let mut sec = 0;
let mut nsec = 0;
unsafe {
ocall_clock_gettime(clockid as clockid_t, &mut sec as *mut time_t, &mut nsec as *mut i64);
}
Ok(timespec_t { sec, nsec })
}
extern "C" {
fn ocall_clock_gettime(clockid: clockid_t, sec: *mut time_t, ns: *mut i64) -> sgx_status_t;
}
// For SEFS
pub struct OcclumTimeProvider;
impl TimeProvider for OcclumTimeProvider {

@ -5,6 +5,7 @@
#include <unistd.h>
#include <pwd.h>
#include <sys/time.h>
#include <time.h>
#define MAX_PATH FILENAME_MAX
@ -205,6 +206,13 @@ void ocall_gettimeofday(long* seconds, long* microseconds) {
*microseconds = tv.tv_usec;
}
void ocall_clock_gettime(int clockid, time_t* sec, long* ns) {
struct timespec ts;
clock_gettime(clockid, &ts);
*sec = ts.tv_sec;
*ns = ts.tv_nsec;
}
void ocall_sync(void) {
sync();
}

40
test/include/test.h Normal file

@ -0,0 +1,40 @@
#ifndef __TEST_H
#define __TEST_H
#include <stdio.h>
#define _STR(x) #x
#define STR(x) _STR(x)
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
typedef int(*test_case_func_t)(void);
typedef struct {
const char* name;
test_case_func_t func;
} test_case_t;
#define TEST_CASE(name) { STR(name), name }
#define throw_error(msg) while(1) { \
printf("\t\tERROR: %s in func %s at line %d of file %s\n", \
(msg), __func__, __LINE__, __FILE__); \
return -1; \
}
int test_suite_run(test_case_t* test_cases, int num_test_cases) {
for (int ti = 0; ti < num_test_cases; ti++) {
test_case_t* tc = &test_cases[ti];
if (tc->func() < 0) {
printf(" func %s - [ERR]\n", tc->name);
return -1;
}
printf(" func %s - [OK]\n", tc->name);
}
return 0;
}
#endif /* __TEST_H */

@ -7,6 +7,7 @@
#include <assert.h>
#include <string.h>
#include <fcntl.h>
#include "test.h"
// ============================================================================
// Helper macros
@ -16,23 +17,9 @@
#define MB (1024 * 1024UL)
#define PAGE_SIZE (4 * KB)
#define _STR(x) #x
#define STR(x) _STR(x)
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
#define ALIGN_DOWN(x, a) ((x) & ~(a-1)) // a must be a power of two
#define ALIGN_UP(x, a) ALIGN_DOWN((x+(a-1)), (a))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define throw_error(msg) while(1) { \
printf("ERROR: %s in func %s at line %d of file %s\n", \
(msg), __func__, __LINE__, __FILE__); \
return -1; \
}
#define MAX_MMAP_USED_MEMORY (4 * MB)
// ============================================================================
@ -632,14 +619,6 @@ int test_munmap_with_non_page_aligned_len() {
// Test suite main
// ============================================================================
typedef int(*test_case_func_t)(void);
typedef struct {
const char* name;
test_case_func_t func;
} test_case_t;
#define TEST_CASE(name) { STR(name), name }
static test_case_t test_cases[] = {
TEST_CASE(test_anonymous_mmap),
TEST_CASE(test_anonymous_mmap_randomly),
@ -669,13 +648,5 @@ int main() {
throw_error("test_suite_init failed");
}
for (int ti = 0; ti < ARRAY_SIZE(test_cases); ti++) {
test_case_t* tc = &test_cases[ti];
if (tc->func() < 0) {
printf(" func %s - [ERR]\n", tc->name);
return -1;
}
printf(" func %s - [OK]\n", tc->name);
}
return 0;
return test_suite_run(test_cases, ARRAY_SIZE(test_cases));
}

@ -19,7 +19,7 @@ READELF_FILE := bin.readelf
CLANG_BIN_PATH := $(shell clang -print-prog-name=clang)
LLVM_PATH := $(abspath $(dir $(CLANG_BIN_PATH))../)
C_FLAGS = -Wall -O2 -fPIC $(EXTRA_C_FLAGS)
C_FLAGS = -Wall -I../include -O2 -fPIC $(EXTRA_C_FLAGS)
C_FLAGS += -Xclang -load -Xclang $(LLVM_PATH)/lib/LLVMMDSFIIRInserter.so
LINK_FLAGS = $(C_FLAGS) -pie -locclum_stub $(EXTRA_LINK_FLAGS)

@ -1,9 +1,43 @@
#include <sys/time.h>
#include <stdio.h>
#include <time.h>
#include "test.h"
int main(int argc, const char* argv[]) {
// ============================================================================
// Test cases for gettimeofday
// ============================================================================
int test_gettimeofday() {
struct timeval tv;
gettimeofday(&tv, NULL);
printf("sec = %lu, usec = %lu\n", tv.tv_sec, tv.tv_usec);
if (gettimeofday(&tv, NULL)) {
throw_error("gettimeofday failed");
}
return 0;
}
// ============================================================================
// Test cases for clock_gettime
// ============================================================================
int test_clock_gettime() {
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts)) {
throw_error("clock_gettime(CLOCK_REALTIME, ...) failed");
}
if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
throw_error("clock_gettime(CLOCK_MONOTONIC, ...) failed");
}
return 0;
}
// ============================================================================
// Test suite
// ============================================================================
static test_case_t test_cases[] = {
TEST_CASE(test_gettimeofday),
TEST_CASE(test_clock_gettime),
};
int main() {
return test_suite_run(test_cases, ARRAY_SIZE(test_cases));
}