@@ -161,8 +161,9 @@ pub unsafe fn context_switch(interrupted: bool) {
161161}
162162
163163/// Clone context
164- ///
164+ /// # Safety
165165/// Unsafe due to interrupt disabling, C memory handling, and raw pointers
166+ #[ cfg( target_arch="x86" ) ]
166167pub unsafe extern "cdecl" fn context_clone ( parent_ptr : * const Context ,
167168 flags : usize ,
168169 clone_pid : usize ) {
@@ -262,6 +263,110 @@ pub unsafe extern "cdecl" fn context_clone(parent_ptr: *const Context,
262263 do_sys_exit ( 0 ) ;
263264}
264265
266+ /// Clone context
267+ /// # Safety
268+ /// Unsafe due to interrupt disabling, C memory handling, and raw pointers
269+ #[ cfg( target_arch="x86_64" ) ]
270+ pub unsafe extern "cdecl" fn context_clone ( /*Throw away extra params from ABI*/ _rdi : usize , _rsi : usize , _rdx : usize , _rcx : usize , _r8 : usize , _r9 : usize ,
271+ parent_ptr : * const Context ,
272+ flags : usize ,
273+ clone_pid : usize ) {
274+ {
275+ let mut contexts = :: env ( ) . contexts . lock ( ) ;
276+
277+ let kernel_stack = memory:: alloc ( CONTEXT_STACK_SIZE + 512 ) ;
278+ if kernel_stack > 0 {
279+ let parent = & * parent_ptr;
280+
281+ :: memcpy ( kernel_stack as * mut u8 ,
282+ parent. kernel_stack as * const u8 ,
283+ CONTEXT_STACK_SIZE + 512 ) ;
284+
285+ let context = box Context {
286+ pid : clone_pid,
287+ ppid : parent. pid ,
288+ name : parent. name . clone ( ) ,
289+ interrupted : parent. interrupted ,
290+ exited : parent. exited ,
291+ slices : CONTEXT_SLICES ,
292+ slice_total : 0 ,
293+
294+ kernel_stack : kernel_stack,
295+ sp : parent. sp - parent. kernel_stack + kernel_stack,
296+ flags : parent. flags ,
297+ fx : kernel_stack + CONTEXT_STACK_SIZE ,
298+ stack : if let Some ( ref entry) = parent. stack {
299+ let physical_address = memory:: alloc ( entry. virtual_size ) ;
300+ if physical_address > 0 {
301+ :: memcpy ( physical_address as * mut u8 ,
302+ entry. physical_address as * const u8 ,
303+ entry. virtual_size ) ;
304+ Some ( ContextMemory {
305+ physical_address : physical_address,
306+ virtual_address : entry. virtual_address ,
307+ virtual_size : entry. virtual_size ,
308+ writeable : entry. writeable ,
309+ allocated : true ,
310+ } )
311+ } else {
312+ None
313+ }
314+ } else {
315+ None
316+ } ,
317+ loadable : parent. loadable ,
318+
319+ cwd : if flags & CLONE_FS == CLONE_FS {
320+ parent. cwd . clone ( )
321+ } else {
322+ Arc :: new ( UnsafeCell :: new ( ( * parent. cwd . get ( ) ) . clone ( ) ) )
323+ } ,
324+ memory : if flags & CLONE_VM == CLONE_VM {
325+ parent. memory . clone ( )
326+ } else {
327+ let mut mem: Vec < ContextMemory > = Vec :: new ( ) ;
328+ for entry in ( * parent. memory . get ( ) ) . iter ( ) {
329+ let physical_address = memory:: alloc ( entry. virtual_size ) ;
330+ if physical_address > 0 {
331+ :: memcpy ( physical_address as * mut u8 ,
332+ entry. physical_address as * const u8 ,
333+ entry. virtual_size ) ;
334+ mem. push ( ContextMemory {
335+ physical_address : physical_address,
336+ virtual_address : entry. virtual_address ,
337+ virtual_size : entry. virtual_size ,
338+ writeable : entry. writeable ,
339+ allocated : true ,
340+ } ) ;
341+ }
342+ }
343+ Arc :: new ( UnsafeCell :: new ( mem) )
344+ } ,
345+ files : if flags & CLONE_FILES == CLONE_FILES {
346+ parent. files . clone ( )
347+ } else {
348+ let mut files: Vec < ContextFile > = Vec :: new ( ) ;
349+ for file in ( * parent. files . get ( ) ) . iter ( ) {
350+ if let Ok ( resource) = file. resource . dup ( ) {
351+ files. push ( ContextFile {
352+ fd : file. fd ,
353+ resource : resource,
354+ } ) ;
355+ }
356+ }
357+ Arc :: new ( UnsafeCell :: new ( files) )
358+ } ,
359+
360+ statuses : Vec :: new ( ) ,
361+ } ;
362+
363+ contexts. push ( context) ;
364+ }
365+ }
366+
367+ do_sys_exit ( 0 ) ;
368+ }
369+
265370// Must have absolutely no pushes or pops
266371#[ cfg( target_arch = "x86" ) ]
267372#[ allow( unused_variables) ]
@@ -282,7 +387,8 @@ pub unsafe extern "cdecl" fn context_userspace(ip: usize,
282387// Must have absolutely no pushes or pops
283388#[ cfg( target_arch = "x86_64" ) ]
284389#[ allow( unused_variables) ]
285- pub unsafe extern "cdecl" fn context_userspace ( ip : usize ,
390+ pub unsafe extern "cdecl" fn context_userspace ( /*Throw away extra params from ABI*/ _rdi : usize , _rsi : usize , _rdx : usize , _rcx : usize , _r8 : usize , _r9 : usize ,
391+ ip : usize ,
286392 cs : usize ,
287393 flags : usize ,
288394 sp : usize ,
@@ -296,9 +402,22 @@ pub unsafe extern "cdecl" fn context_userspace(ip: usize,
296402}
297403
298404/// Reads a Boxed function and executes it
299- ///
405+ /// # Safety
406+ /// Unsafe due to raw memory handling and FnBox
407+ #[ cfg( target_arch="x86" ) ]
408+ unsafe extern "cdecl" fn context_box ( box_fn_ptr : usize ) {
409+ let box_fn = ptr:: read ( box_fn_ptr as * mut Box < FnBox ( ) > ) ;
410+ memory:: unalloc ( box_fn_ptr) ;
411+ box_fn ( ) ;
412+ do_sys_exit ( 0 ) ;
413+ }
414+
415+ /// Reads a Boxed function and executes it
416+ /// # Safety
300417/// Unsafe due to raw memory handling and FnBox
301- pub unsafe extern "cdecl" fn context_box ( box_fn_ptr : usize ) {
418+ #[ cfg( target_arch="x86_64" ) ]
419+ unsafe extern "cdecl" fn context_box ( /*Throw away extra params from ABI*/ _rdi : usize , _rsi : usize , _rdx : usize , _rcx : usize , _r8 : usize , _r9 : usize ,
420+ box_fn_ptr : usize ) {
302421 let box_fn = ptr:: read ( box_fn_ptr as * mut Box < FnBox ( ) > ) ;
303422 memory:: unalloc ( box_fn_ptr) ;
304423 box_fn ( ) ;
0 commit comments