Add gettimeofday
This commit is contained in:
		
							parent
							
								
									1644159832
								
							
						
					
					
						commit
						d3009db10b
					
				| @ -14,5 +14,6 @@ enclave { | |||||||
|     untrusted { |     untrusted { | ||||||
|         void ocall_print_string([in, string] const char* msg); |         void ocall_print_string([in, string] const char* msg); | ||||||
|         int ocall_run_new_task(void); |         int ocall_run_new_task(void); | ||||||
|  |         void ocall_gettimeofday([out] long* seconds, [out] long* microseconds); | ||||||
|     }; |     }; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ | |||||||
| #include "syscall_nr.h" | #include "syscall_nr.h" | ||||||
| 
 | 
 | ||||||
| struct iovec; | struct iovec; | ||||||
|  | struct timeval; | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| @ -38,6 +39,8 @@ extern int occlum_munmap(void *addr, size_t length); | |||||||
| extern void *occlum_mremap(void *old_address, size_t old_size, size_t new_size, int flags, void *new_address); | extern void *occlum_mremap(void *old_address, size_t old_size, size_t new_size, int flags, void *new_address); | ||||||
| extern void* occlum_brk(void* addr); | extern void* occlum_brk(void* addr); | ||||||
| 
 | 
 | ||||||
|  | extern int occlum_gettimeofday(struct timeval* tv/*, struct timezone* tz*/); | ||||||
|  | 
 | ||||||
| extern int occlum_unknown(int num); | extern int occlum_unknown(int num); | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|  | |||||||
| @ -32,6 +32,7 @@ mod process; | |||||||
| mod syscall; | mod syscall; | ||||||
| mod vm; | mod vm; | ||||||
| mod util; | mod util; | ||||||
|  | mod time; | ||||||
| 
 | 
 | ||||||
| use prelude::*; | use prelude::*; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,11 +1,12 @@ | |||||||
| use super::*; | use super::*; | ||||||
| use prelude::*; | use prelude::*; | ||||||
| use std::{ptr}; |  | ||||||
| use {std, fs, process, vm}; | use {std, fs, process, vm}; | ||||||
|  | use std::{ptr}; | ||||||
| use std::ffi::{CStr, CString}; | use std::ffi::{CStr, CString}; | ||||||
| use fs::{off_t, FileDesc}; | use fs::{off_t, FileDesc}; | ||||||
| use vm::{VMAreaFlags, VMResizeOptions}; | use vm::{VMAreaFlags, VMResizeOptions}; | ||||||
| use process::{pid_t, ChildProcessFilter, FileAction}; | use process::{pid_t, ChildProcessFilter, FileAction}; | ||||||
|  | use time::{timeval_t}; | ||||||
| // Use the internal syscall wrappers from sgx_tstd
 | // Use the internal syscall wrappers from sgx_tstd
 | ||||||
| //use std::libc_fs as fs;
 | //use std::libc_fs as fs;
 | ||||||
| //use std::libc_io as io;
 | //use std::libc_io as io;
 | ||||||
| @ -50,6 +51,81 @@ fn clone_cstrings_from_user_safely(user_ptr: *const *const c_char) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /* | ||||||
|  |  * This Rust-version of fdop correspond to the C-version one in Occlum. | ||||||
|  |  * See <path_to_musl_libc>/src/process/fdop.h. | ||||||
|  |  */ | ||||||
|  | const FDOP_CLOSE : u32 = 1; | ||||||
|  | const FDOP_DUP2 : u32 = 2; | ||||||
|  | const FDOP_OPEN : u32 = 3; | ||||||
|  | 
 | ||||||
|  | #[repr(C)] | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct FdOp { | ||||||
|  |     // We actually switch the prev and next fields in the libc definition.
 | ||||||
|  |     prev: *const FdOp, | ||||||
|  |     next: *const FdOp, | ||||||
|  |     cmd: u32, | ||||||
|  |     fd: u32, | ||||||
|  |     srcfd: u32, | ||||||
|  |     oflag: u32, | ||||||
|  |     mode: u32, | ||||||
|  |     path: *const u8, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn clone_file_actions_from_user_safely(fdop_ptr: *const FdOp) | ||||||
|  |     -> Result<Vec<FileAction>, Error> | ||||||
|  | { | ||||||
|  |     let mut file_actions = Vec::new(); | ||||||
|  | 
 | ||||||
|  |     let mut fdop_ptr = fdop_ptr; | ||||||
|  |     while fdop_ptr != ptr::null() { | ||||||
|  |         check_ptr_from_user(fdop_ptr)?; | ||||||
|  |         let fdop = unsafe { &*fdop_ptr }; | ||||||
|  | 
 | ||||||
|  |         let file_action = match fdop.cmd { | ||||||
|  |             FDOP_CLOSE => { | ||||||
|  |                 FileAction::Close(fdop.fd) | ||||||
|  |             }, | ||||||
|  |             FDOP_DUP2 => { | ||||||
|  |                 FileAction::Dup2(fdop.srcfd, fdop.fd) | ||||||
|  |             }, | ||||||
|  |             FDOP_OPEN => { | ||||||
|  |                 return errno!(EINVAL, "Not implemented"); | ||||||
|  |             }, | ||||||
|  |             _ => { | ||||||
|  |                 return errno!(EINVAL, "Unknown file action command"); | ||||||
|  |             }, | ||||||
|  |         }; | ||||||
|  |         file_actions.push(file_action); | ||||||
|  | 
 | ||||||
|  |         fdop_ptr = fdop.next; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Ok(file_actions) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn do_spawn(child_pid_ptr: *mut c_uint, | ||||||
|  |             path: *const c_char, | ||||||
|  |             argv: *const *const c_char, | ||||||
|  |             envp: *const *const c_char, | ||||||
|  |             fdop_list: *const FdOp, | ||||||
|  |             ) | ||||||
|  |     -> Result<(), Error> | ||||||
|  | { | ||||||
|  |     check_mut_ptr_from_user(child_pid_ptr)?; | ||||||
|  |     let path = clone_cstring_from_user_safely(path)?; | ||||||
|  |     let argv = clone_cstrings_from_user_safely(argv)?; | ||||||
|  |     let envp = clone_cstrings_from_user_safely(envp)?; | ||||||
|  |     let file_actions = clone_file_actions_from_user_safely(fdop_list)?; | ||||||
|  |     let parent = process::get_current(); | ||||||
|  | 
 | ||||||
|  |     let child_pid = process::do_spawn(&path, &argv, &envp, &file_actions, &parent)?; | ||||||
|  | 
 | ||||||
|  |     unsafe { *child_pid_ptr = child_pid }; | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| fn do_read(fd: c_int, buf: *mut c_void, size: size_t) | fn do_read(fd: c_int, buf: *mut c_void, size: size_t) | ||||||
|     -> Result<size_t, Error> |     -> Result<size_t, Error> | ||||||
| { | { | ||||||
| @ -244,6 +320,13 @@ fn do_pipe2(fds_u: *mut c_int, flags: c_int) -> Result<(), Error> { | |||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | fn do_gettimeofday(tv_u: *mut timeval_t) -> Result<(), Error> { | ||||||
|  |     check_mut_ptr_from_user(tv_u)?; | ||||||
|  |     let tv = time::do_gettimeofday(); | ||||||
|  |     unsafe { *tv_u = tv; } | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| const MAP_FAILED : *const c_void = ((-1) as i64) as *const c_void; | const MAP_FAILED : *const c_void = ((-1) as i64) as *const c_void; | ||||||
| 
 | 
 | ||||||
| @ -414,82 +497,6 @@ pub extern "C" fn occlum_unknown(num: u32) | |||||||
|     println!("[WARNING] Unknown syscall (num = {})", num); |     println!("[WARNING] Unknown syscall (num = {})", num); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|  * This Rust-version of fdop correspond to the C-version one in Occlum. |  | ||||||
|  * See <path_to_musl_libc>/src/process/fdop.h. |  | ||||||
|  */ |  | ||||||
| const FDOP_CLOSE : u32 = 1; |  | ||||||
| const FDOP_DUP2 : u32 = 2; |  | ||||||
| const FDOP_OPEN : u32 = 3; |  | ||||||
| 
 |  | ||||||
| #[repr(C)] |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub struct FdOp { |  | ||||||
|     // We actually switch the prev and next fields in the libc definition.
 |  | ||||||
|     prev: *const FdOp, |  | ||||||
|     next: *const FdOp, |  | ||||||
|     cmd: u32, |  | ||||||
|     fd: u32, |  | ||||||
|     srcfd: u32, |  | ||||||
|     oflag: u32, |  | ||||||
|     mode: u32, |  | ||||||
|     path: *const u8, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn clone_file_actions_from_user_safely(fdop_ptr: *const FdOp) |  | ||||||
|     -> Result<Vec<FileAction>, Error> |  | ||||||
| { |  | ||||||
|     let mut file_actions = Vec::new(); |  | ||||||
| 
 |  | ||||||
|     let mut fdop_ptr = fdop_ptr; |  | ||||||
|     while fdop_ptr != ptr::null() { |  | ||||||
|         check_ptr_from_user(fdop_ptr)?; |  | ||||||
|         let fdop = unsafe { &*fdop_ptr }; |  | ||||||
| 
 |  | ||||||
|         let file_action = match fdop.cmd { |  | ||||||
|             FDOP_CLOSE => { |  | ||||||
|                 FileAction::Close(fdop.fd) |  | ||||||
|             }, |  | ||||||
|             FDOP_DUP2 => { |  | ||||||
|                 FileAction::Dup2(fdop.srcfd, fdop.fd) |  | ||||||
|             }, |  | ||||||
|             FDOP_OPEN => { |  | ||||||
|                 return errno!(EINVAL, "Not implemented"); |  | ||||||
|             }, |  | ||||||
|             _ => { |  | ||||||
|                 return errno!(EINVAL, "Unknown file action command"); |  | ||||||
|             }, |  | ||||||
|         }; |  | ||||||
|         file_actions.push(file_action); |  | ||||||
| 
 |  | ||||||
|         fdop_ptr = fdop.next; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     Ok(file_actions) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn do_spawn(child_pid_ptr: *mut c_uint, |  | ||||||
|             path: *const c_char, |  | ||||||
|             argv: *const *const c_char, |  | ||||||
|             envp: *const *const c_char, |  | ||||||
|             fdop_list: *const FdOp, |  | ||||||
|             ) |  | ||||||
|     -> Result<(), Error> |  | ||||||
| { |  | ||||||
|     check_mut_ptr_from_user(child_pid_ptr)?; |  | ||||||
|     let path = clone_cstring_from_user_safely(path)?; |  | ||||||
|     let argv = clone_cstrings_from_user_safely(argv)?; |  | ||||||
|     let envp = clone_cstrings_from_user_safely(envp)?; |  | ||||||
|     let file_actions = clone_file_actions_from_user_safely(fdop_list)?; |  | ||||||
|     let parent = process::get_current(); |  | ||||||
| 
 |  | ||||||
|     let child_pid = process::do_spawn(&path, &argv, &envp, &file_actions, &parent)?; |  | ||||||
| 
 |  | ||||||
|     unsafe { *child_pid_ptr = child_pid }; |  | ||||||
|     Ok(()) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub extern "C" fn occlum_spawn( | pub extern "C" fn occlum_spawn( | ||||||
|     child_pid: *mut c_uint, path: *const c_char, |     child_pid: *mut c_uint, path: *const c_char, | ||||||
| @ -562,3 +569,17 @@ pub extern "C" fn occlum_dup3(old_fd: c_int, new_fd: c_int, flags: c_int) | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // TODO: handle tz: timezone_t
 | ||||||
|  | #[no_mangle] | ||||||
|  | pub extern "C" fn occlum_gettimeofday(tv: *mut timeval_t) -> c_int | ||||||
|  | { | ||||||
|  |     match do_gettimeofday(tv) { | ||||||
|  |         Ok(()) => { | ||||||
|  |             0 | ||||||
|  |         } | ||||||
|  |         Err(e) => { | ||||||
|  |             e.errno.as_retval() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | |||||||
| @ -144,6 +144,12 @@ long dispatch_syscall(int num, long arg0, long arg1, long arg2, long arg3, long | |||||||
|         ret = (long) occlum_dup3(old_fd, new_fd, flags); |         ret = (long) occlum_dup3(old_fd, new_fd, flags); | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  |     case SYS_gettimeofday: { | ||||||
|  |         DECL_SYSCALL_ARG(struct timeval*, tv, arg0); | ||||||
|  |         //DECL_SYSCALL_ARG(struct timezone*, tz, arg1);
 | ||||||
|  |         ret = (long) occlum_gettimeofday(tv/*, tz*/); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|     default: |     default: | ||||||
|         ret = occlum_unknown(num); |         ret = occlum_unknown(num); | ||||||
|         break; |         break; | ||||||
|  | |||||||
							
								
								
									
										27
									
								
								src/libos/src/time/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										27
									
								
								src/libos/src/time/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | use super::*; | ||||||
|  | 
 | ||||||
|  | #[allow(non_camel_case_types)] | ||||||
|  | pub type time_t = i64; | ||||||
|  | 
 | ||||||
|  | #[allow(non_camel_case_types)] | ||||||
|  | pub type suseconds_t = i64; | ||||||
|  | 
 | ||||||
|  | #[repr(C)] | ||||||
|  | #[derive(Debug, Default, Copy, Clone)] | ||||||
|  | pub struct timeval_t { | ||||||
|  |     sec: time_t, | ||||||
|  |     usec: suseconds_t, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn do_gettimeofday() -> timeval_t { | ||||||
|  |     let mut tv : timeval_t = Default::default(); | ||||||
|  |     unsafe { | ||||||
|  |         ocall_gettimeofday(&mut tv.sec as *mut time_t, | ||||||
|  |                            &mut tv.usec as *mut suseconds_t); | ||||||
|  |     } | ||||||
|  |     tv | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | extern { | ||||||
|  |     fn ocall_gettimeofday(sec: *mut time_t, usec: *mut suseconds_t) -> sgx_status_t; | ||||||
|  | } | ||||||
| @ -4,6 +4,7 @@ | |||||||
| 
 | 
 | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <pwd.h> | #include <pwd.h> | ||||||
|  | #include <sys/time.h> | ||||||
| 
 | 
 | ||||||
| #define MAX_PATH FILENAME_MAX | #define MAX_PATH FILENAME_MAX | ||||||
| 
 | 
 | ||||||
| @ -197,6 +198,13 @@ int ocall_run_new_task(void) { | |||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void ocall_gettimeofday(long* seconds, long* microseconds) { | ||||||
|  |     struct timeval tv; | ||||||
|  |     gettimeofday(&tv, NULL); | ||||||
|  |     *seconds = tv.tv_sec; | ||||||
|  |     *microseconds = tv.tv_usec; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /* Application entry */ | /* Application entry */ | ||||||
| int SGX_CDECL main(int argc, char *argv[]) | int SGX_CDECL main(int argc, char *argv[]) | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) | CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) | ||||||
| PROJECT_DIR := $(realpath $(CUR_DIR)/../) | PROJECT_DIR := $(realpath $(CUR_DIR)/../) | ||||||
| 
 | 
 | ||||||
| TEST_SUITES := empty hello_world malloc file getpid spawn pipe | TEST_SUITES := empty hello_world malloc file getpid spawn pipe time | ||||||
| BUILD_TEST_SUITES := $(TEST_SUITES:%=%) | BUILD_TEST_SUITES := $(TEST_SUITES:%=%) | ||||||
| RUN_TEST_SUITES := $(TEST_SUITES:%=test-%) | RUN_TEST_SUITES := $(TEST_SUITES:%=test-%) | ||||||
| CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%) | CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%) | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								test/time/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										4
									
								
								test/time/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | include ../test_common.mk | ||||||
|  | 
 | ||||||
|  | EXTRA_C_FLAGS := | ||||||
|  | EXTRA_LINK_FLAGS := | ||||||
							
								
								
									
										9
									
								
								test/time/main.c
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										9
									
								
								test/time/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | #include <sys/time.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | 
 | ||||||
|  | int main() { | ||||||
|  |     struct timeval tv; | ||||||
|  |     gettimeofday(&tv, NULL); | ||||||
|  |     printf("sec = %lu, usec = %lu\n", tv.tv_sec, tv.tv_usec); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user