Skip to content

Commit d2cf9f8

Browse files
committed
Cleanup elf loader, print more useful error messages
1 parent 1969d07 commit d2cf9f8

File tree

3 files changed

+443
-358
lines changed

3 files changed

+443
-358
lines changed

kernel/arch/context.rs

Lines changed: 123 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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")]
166167
pub 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

Comments
 (0)