Add signal support - exit on signal
This commit is contained in:
parent
b551b30300
commit
bf292bc0d1
31 changed files with 393 additions and 311 deletions
6
.gitmodules
vendored
6
.gitmodules
vendored
|
|
@ -1,9 +1,6 @@
|
||||||
[submodule "rust"]
|
[submodule "rust"]
|
||||||
path = rust
|
path = rust
|
||||||
url = https://github.com/redox-os/rust.git
|
url = https://github.com/redox-os/rust.git
|
||||||
[submodule "libstd"]
|
|
||||||
path = libstd
|
|
||||||
url = https://github.com/redox-os/libstd.git
|
|
||||||
[submodule "ion"]
|
[submodule "ion"]
|
||||||
path = programs/ion
|
path = programs/ion
|
||||||
url = https://github.com/redox-os/ion.git
|
url = https://github.com/redox-os/ion.git
|
||||||
|
|
@ -52,3 +49,6 @@
|
||||||
[submodule "crates/docgen"]
|
[submodule "crates/docgen"]
|
||||||
path = crates/docgen
|
path = crates/docgen
|
||||||
url = https://github.com/redox-os/docgen.git
|
url = https://github.com/redox-os/docgen.git
|
||||||
|
[submodule "libstd_real/openlibm"]
|
||||||
|
path = libstd/openlibm
|
||||||
|
url = https://github.com/redox-os/openlibm.git
|
||||||
|
|
|
||||||
12
Makefile
12
Makefile
|
|
@ -28,7 +28,6 @@ FORCE:
|
||||||
clean:
|
clean:
|
||||||
cargo clean
|
cargo clean
|
||||||
cargo clean --manifest-path libstd/Cargo.toml
|
cargo clean --manifest-path libstd/Cargo.toml
|
||||||
cargo clean --manifest-path libstd_real/Cargo.toml
|
|
||||||
cargo clean --manifest-path drivers/ahcid/Cargo.toml
|
cargo clean --manifest-path drivers/ahcid/Cargo.toml
|
||||||
cargo clean --manifest-path drivers/e1000d/Cargo.toml
|
cargo clean --manifest-path drivers/e1000d/Cargo.toml
|
||||||
cargo clean --manifest-path drivers/ps2d/Cargo.toml
|
cargo clean --manifest-path drivers/ps2d/Cargo.toml
|
||||||
|
|
@ -82,7 +81,6 @@ ref: FORCE
|
||||||
test:
|
test:
|
||||||
cargo test
|
cargo test
|
||||||
cargo test --manifest-path libstd/Cargo.toml
|
cargo test --manifest-path libstd/Cargo.toml
|
||||||
cargo test --manifest-path libstd_real/Cargo.toml
|
|
||||||
cargo test --manifest-path drivers/ahcid/Cargo.toml
|
cargo test --manifest-path drivers/ahcid/Cargo.toml
|
||||||
cargo test --manifest-path drivers/e1000d/Cargo.toml
|
cargo test --manifest-path drivers/e1000d/Cargo.toml
|
||||||
cargo test --manifest-path drivers/ps2d/Cargo.toml
|
cargo test --manifest-path drivers/ps2d/Cargo.toml
|
||||||
|
|
@ -114,7 +112,6 @@ test:
|
||||||
update:
|
update:
|
||||||
cargo update
|
cargo update
|
||||||
cargo update --manifest-path libstd/Cargo.toml
|
cargo update --manifest-path libstd/Cargo.toml
|
||||||
cargo update --manifest-path libstd_real/Cargo.toml
|
|
||||||
cargo update --manifest-path drivers/ahcid/Cargo.toml
|
cargo update --manifest-path drivers/ahcid/Cargo.toml
|
||||||
cargo update --manifest-path drivers/e1000d/Cargo.toml
|
cargo update --manifest-path drivers/e1000d/Cargo.toml
|
||||||
cargo update --manifest-path drivers/ps2d/Cargo.toml
|
cargo update --manifest-path drivers/ps2d/Cargo.toml
|
||||||
|
|
@ -314,13 +311,9 @@ $(BUILD)/libopenlibm.a: libstd/openlibm/libopenlibm.a
|
||||||
mkdir -p $(BUILD)
|
mkdir -p $(BUILD)
|
||||||
cp $< $@
|
cp $< $@
|
||||||
|
|
||||||
#$(BUILD)/libstd.rlib: libstd/Cargo.toml libstd/src/** $(BUILD)/libcore.rlib $(BUILD)/liballoc.rlib $(BUILD)/librustc_unicode.rlib $(BUILD)/libcollections.rlib $(BUILD)/librand.rlib $(BUILD)/libopenlibm.a
|
$(BUILD)/libstd.rlib: libstd/Cargo.toml rust/src/libstd/** $(BUILD)/libcore.rlib $(BUILD)/liballoc.rlib $(BUILD)/librustc_unicode.rlib $(BUILD)/libcollections.rlib $(BUILD)/librand.rlib $(BUILD)/libopenlibm.a
|
||||||
# $(CARGO) rustc --verbose --manifest-path $< $(CARGOFLAGS) -o $@
|
|
||||||
# cp libstd/target/$(TARGET)/release/deps/*.rlib $(BUILD)
|
|
||||||
|
|
||||||
$(BUILD)/libstd.rlib: libstd_real/Cargo.toml rust/src/libstd/** $(BUILD)/libcore.rlib $(BUILD)/liballoc.rlib $(BUILD)/librustc_unicode.rlib $(BUILD)/libcollections.rlib $(BUILD)/librand.rlib $(BUILD)/libopenlibm.a
|
|
||||||
$(CARGO) rustc --verbose --manifest-path $< $(CARGOFLAGS) -o $@
|
$(CARGO) rustc --verbose --manifest-path $< $(CARGOFLAGS) -o $@
|
||||||
cp libstd_real/target/$(TARGET)/release/deps/*.rlib $(BUILD)
|
cp libstd/target/$(TARGET)/release/deps/*.rlib $(BUILD)
|
||||||
|
|
||||||
initfs/bin/%: drivers/%/Cargo.toml drivers/%/src/** $(BUILD)/libstd.rlib
|
initfs/bin/%: drivers/%/Cargo.toml drivers/%/src/** $(BUILD)/libstd.rlib
|
||||||
mkdir -p initfs/bin
|
mkdir -p initfs/bin
|
||||||
|
|
@ -438,6 +431,7 @@ coreutils: \
|
||||||
filesystem/bin/false \
|
filesystem/bin/false \
|
||||||
filesystem/bin/free \
|
filesystem/bin/free \
|
||||||
filesystem/bin/head \
|
filesystem/bin/head \
|
||||||
|
filesystem/bin/kill \
|
||||||
filesystem/bin/ls \
|
filesystem/bin/ls \
|
||||||
filesystem/bin/mkdir \
|
filesystem/bin/mkdir \
|
||||||
filesystem/bin/mv \
|
filesystem/bin/mv \
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use core::mem;
|
||||||
use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT};
|
use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT};
|
||||||
|
|
||||||
/// This must be used by the kernel to ensure that context switches are done atomically
|
/// This must be used by the kernel to ensure that context switches are done atomically
|
||||||
|
|
@ -65,6 +66,23 @@ impl Context {
|
||||||
self.rsp = address;
|
self.rsp = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn signal_stack(&mut self, handler: extern fn(usize), sig: u8) {
|
||||||
|
self.push_stack(sig as usize);
|
||||||
|
self.push_stack(handler as usize);
|
||||||
|
self.push_stack(signal_handler_wrapper as usize);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn push_stack(&mut self, value: usize) {
|
||||||
|
self.rsp -= mem::size_of::<usize>();
|
||||||
|
*(self.rsp as *mut usize) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn pop_stack(&mut self) -> usize {
|
||||||
|
let value = *(self.rsp as *const usize);
|
||||||
|
self.rsp += mem::size_of::<usize>();
|
||||||
|
value
|
||||||
|
}
|
||||||
|
|
||||||
/// Switch to the next context by restoring its stack and registers
|
/// Switch to the next context by restoring its stack and registers
|
||||||
#[cold]
|
#[cold]
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
|
|
@ -108,3 +126,61 @@ impl Context {
|
||||||
asm!("mov rbp, $0" : : "r"(next.rbp) : "memory" : "intel", "volatile");
|
asm!("mov rbp, $0" : : "r"(next.rbp) : "memory" : "intel", "volatile");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(packed)]
|
||||||
|
pub struct SignalHandlerStack {
|
||||||
|
r11: usize,
|
||||||
|
r10: usize,
|
||||||
|
r9: usize,
|
||||||
|
r8: usize,
|
||||||
|
rsi: usize,
|
||||||
|
rdi: usize,
|
||||||
|
rdx: usize,
|
||||||
|
rcx: usize,
|
||||||
|
rax: usize,
|
||||||
|
handler: extern fn(usize),
|
||||||
|
sig: usize,
|
||||||
|
rip: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[naked]
|
||||||
|
unsafe extern fn signal_handler_wrapper() {
|
||||||
|
#[inline(never)]
|
||||||
|
unsafe fn inner(stack: &SignalHandlerStack) {
|
||||||
|
(stack.handler)(stack.sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push scratch registers
|
||||||
|
asm!("xchg bx, bx
|
||||||
|
push rax
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
push rdi
|
||||||
|
push rsi
|
||||||
|
push r8
|
||||||
|
push r9
|
||||||
|
push r10
|
||||||
|
push r11"
|
||||||
|
: : : : "intel", "volatile");
|
||||||
|
|
||||||
|
// Get reference to stack variables
|
||||||
|
let rsp: usize;
|
||||||
|
asm!("" : "={rsp}"(rsp) : : : "intel", "volatile");
|
||||||
|
|
||||||
|
// Call inner rust function
|
||||||
|
inner(&*(rsp as *const SignalHandlerStack));
|
||||||
|
|
||||||
|
// Pop scratch registers, error code, and return
|
||||||
|
asm!("xchg bx, bx
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
pop rsi
|
||||||
|
pop rdi
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rax
|
||||||
|
add rsp, 16"
|
||||||
|
: : : : "intel", "volatile");
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
use super::{halt, stack_trace};
|
use interrupt::stack_trace;
|
||||||
|
|
||||||
use syscall::flag::*;
|
use syscall::flag::*;
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
|
|
@ -8,9 +7,8 @@ extern {
|
||||||
|
|
||||||
interrupt_stack!(divide_by_zero, stack, {
|
interrupt_stack!(divide_by_zero, stack, {
|
||||||
println!("Divide by zero fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
println!("Divide by zero fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
||||||
ksignal(SIGFPE);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGFPE);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_stack!(debug, stack, {
|
interrupt_stack!(debug, stack, {
|
||||||
|
|
@ -34,107 +32,92 @@ interrupt_stack!(overflow, stack, {
|
||||||
|
|
||||||
interrupt_stack!(bound_range, stack, {
|
interrupt_stack!(bound_range, stack, {
|
||||||
println!("Bound range exceeded fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
println!("Bound range exceeded fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
||||||
ksignal(SIGSEGV);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGSEGV);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_stack!(invalid_opcode, stack, {
|
interrupt_stack!(invalid_opcode, stack, {
|
||||||
println!("Invalid opcode fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
println!("Invalid opcode fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
||||||
ksignal(SIGILL);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGILL);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_stack!(device_not_available, stack, {
|
interrupt_stack!(device_not_available, stack, {
|
||||||
println!("Device not available fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
println!("Device not available fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
||||||
ksignal(SIGILL);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGILL);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_error!(double_fault, stack, {
|
interrupt_error!(double_fault, stack, {
|
||||||
println!("Double fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
println!("Double fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
||||||
ksignal(SIGSEGV);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGSEGV);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_error!(invalid_tss, stack, {
|
interrupt_error!(invalid_tss, stack, {
|
||||||
println!("Invalid TSS fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
println!("Invalid TSS fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
||||||
ksignal(SIGSEGV);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGSEGV);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_error!(segment_not_present, stack, {
|
interrupt_error!(segment_not_present, stack, {
|
||||||
println!("Segment not present fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
println!("Segment not present fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
||||||
ksignal(SIGSEGV);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGSEGV);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_error!(stack_segment, stack, {
|
interrupt_error!(stack_segment, stack, {
|
||||||
println!("Stack segment fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
println!("Stack segment fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
||||||
ksignal(SIGSEGV);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGSEGV);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_error!(protection, stack, {
|
interrupt_error!(protection, stack, {
|
||||||
println!("Protection fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
println!("Protection fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
||||||
ksignal(SIGSEGV);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGSEGV);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_error!(page, stack, {
|
interrupt_error!(page, stack, {
|
||||||
let cr2: usize;
|
let cr2: usize;
|
||||||
asm!("mov rax, cr2" : "={rax}"(cr2) : : : "intel", "volatile");
|
asm!("mov rax, cr2" : "={rax}"(cr2) : : : "intel", "volatile");
|
||||||
println!("Page fault: {:>02X}:{:>016X} at {:>02X}:{:>016X}", stack.code, cr2, stack.cs, stack.rip);
|
println!("Page fault: {:>02X}:{:>016X} at {:>02X}:{:>016X}", stack.code, cr2, stack.cs, stack.rip);
|
||||||
ksignal(SIGSEGV);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGSEGV);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_stack!(fpu, stack, {
|
interrupt_stack!(fpu, stack, {
|
||||||
println!("FPU floating point fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
println!("FPU floating point fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
||||||
ksignal(SIGFPE);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGFPE);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_error!(alignment_check, stack, {
|
interrupt_error!(alignment_check, stack, {
|
||||||
println!("Alignment check fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
println!("Alignment check fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
||||||
ksignal(SIGBUS);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGBUS);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_stack!(machine_check, stack, {
|
interrupt_stack!(machine_check, stack, {
|
||||||
println!("Machine check fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
println!("Machine check fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
||||||
ksignal(SIGBUS);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGBUS);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_stack!(simd, stack, {
|
interrupt_stack!(simd, stack, {
|
||||||
println!("SIMD floating point fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
println!("SIMD floating point fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
||||||
ksignal(SIGFPE);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGFPE);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_stack!(virtualization, stack, {
|
interrupt_stack!(virtualization, stack, {
|
||||||
println!("Virtualization fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
println!("Virtualization fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
|
||||||
ksignal(SIGBUS);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGBUS);
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_error!(security, stack, {
|
interrupt_error!(security, stack, {
|
||||||
println!("Security exception: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
println!("Security exception: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
|
||||||
ksignal(SIGBUS);
|
|
||||||
stack_trace();
|
stack_trace();
|
||||||
loop { halt(); }
|
ksignal(SIGBUS);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use alloc::arc::Arc;
|
use alloc::arc::Arc;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use collections::{BTreeMap, Vec};
|
use collections::{BTreeMap, Vec, VecDeque};
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
use arch;
|
use arch;
|
||||||
|
|
@ -48,6 +48,8 @@ pub struct Context {
|
||||||
pub vfork: bool,
|
pub vfork: bool,
|
||||||
/// Context is being waited on
|
/// Context is being waited on
|
||||||
pub waitpid: Arc<WaitMap<ContextId, usize>>,
|
pub waitpid: Arc<WaitMap<ContextId, usize>>,
|
||||||
|
/// Context should handle pending signals
|
||||||
|
pub pending: VecDeque<u8>,
|
||||||
/// Context should wake up at specified time
|
/// Context should wake up at specified time
|
||||||
pub wake: Option<(u64, u64)>,
|
pub wake: Option<(u64, u64)>,
|
||||||
/// The architecture specific context
|
/// The architecture specific context
|
||||||
|
|
@ -94,6 +96,7 @@ impl Context {
|
||||||
cpu_id: None,
|
cpu_id: None,
|
||||||
vfork: false,
|
vfork: false,
|
||||||
waitpid: Arc::new(WaitMap::new()),
|
waitpid: Arc::new(WaitMap::new()),
|
||||||
|
pending: VecDeque::new(),
|
||||||
wake: None,
|
wake: None,
|
||||||
arch: arch::context::Context::new(),
|
arch: arch::context::Context::new(),
|
||||||
kfx: None,
|
kfx: None,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
use core::sync::atomic::Ordering;
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
use arch;
|
use arch;
|
||||||
use super::{contexts, Context, Status, CONTEXT_ID};
|
use context::{contexts, Context, Status, CONTEXT_ID};
|
||||||
|
use syscall;
|
||||||
|
|
||||||
/// Switch to the next context
|
/// Switch to the next context
|
||||||
///
|
///
|
||||||
|
|
@ -20,6 +21,7 @@ pub unsafe fn switch() -> bool {
|
||||||
|
|
||||||
let from_ptr;
|
let from_ptr;
|
||||||
let mut to_ptr = 0 as *mut Context;
|
let mut to_ptr = 0 as *mut Context;
|
||||||
|
let mut to_sig = None;
|
||||||
{
|
{
|
||||||
let contexts = contexts();
|
let contexts = contexts();
|
||||||
{
|
{
|
||||||
|
|
@ -34,6 +36,10 @@ pub unsafe fn switch() -> bool {
|
||||||
// println!("{}: take {} {}", cpu_id, context.id, ::core::str::from_utf8_unchecked(&context.name.lock()));
|
// println!("{}: take {} {}", cpu_id, context.id, ::core::str::from_utf8_unchecked(&context.name.lock()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if context.status == Status::Blocked && ! context.pending.is_empty() {
|
||||||
|
context.unblock();
|
||||||
|
}
|
||||||
|
|
||||||
if context.status == Status::Blocked && context.wake.is_some() {
|
if context.status == Status::Blocked && context.wake.is_some() {
|
||||||
let wake = context.wake.expect("context::switch: wake not set");
|
let wake = context.wake.expect("context::switch: wake not set");
|
||||||
|
|
||||||
|
|
@ -57,6 +63,7 @@ pub unsafe fn switch() -> bool {
|
||||||
let mut context = context_lock.write();
|
let mut context = context_lock.write();
|
||||||
if check_context(&mut context) {
|
if check_context(&mut context) {
|
||||||
to_ptr = context.deref_mut() as *mut Context;
|
to_ptr = context.deref_mut() as *mut Context;
|
||||||
|
to_sig = context.pending.pop_front();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -68,6 +75,7 @@ pub unsafe fn switch() -> bool {
|
||||||
let mut context = context_lock.write();
|
let mut context = context_lock.write();
|
||||||
if check_context(&mut context) {
|
if check_context(&mut context) {
|
||||||
to_ptr = context.deref_mut() as *mut Context;
|
to_ptr = context.deref_mut() as *mut Context;
|
||||||
|
to_sig = context.pending.pop_front();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +99,17 @@ pub unsafe fn switch() -> bool {
|
||||||
// Unset global lock before switch, as arch is only usable by the current CPU at this time
|
// Unset global lock before switch, as arch is only usable by the current CPU at this time
|
||||||
arch::context::CONTEXT_SWITCH_LOCK.store(false, Ordering::SeqCst);
|
arch::context::CONTEXT_SWITCH_LOCK.store(false, Ordering::SeqCst);
|
||||||
|
|
||||||
|
if let Some(sig) = to_sig {
|
||||||
|
println!("Handle {}", sig);
|
||||||
|
(&mut *to_ptr).arch.signal_stack(signal_handler, sig);
|
||||||
|
}
|
||||||
|
|
||||||
(&mut *from_ptr).arch.switch_to(&mut (&mut *to_ptr).arch);
|
(&mut *from_ptr).arch.switch_to(&mut (&mut *to_ptr).arch);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern fn signal_handler(signal: usize) {
|
||||||
|
println!("Signal handler: {}", signal);
|
||||||
|
syscall::exit(signal);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,7 @@ pub extern fn ksignal(signal: usize) {
|
||||||
println!("NAME {}", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) });
|
println!("NAME {}", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
syscall::exit(signal & 0x7F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is the kernel entry point for the primary CPU. The arch crate is responsible for calling this
|
/// This is the kernel entry point for the primary CPU. The arch crate is responsible for calling this
|
||||||
|
|
|
||||||
130
kernel/syscall/driver.rs
Normal file
130
kernel/syscall/driver.rs
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
use arch;
|
||||||
|
use arch::memory::{allocate_frames, deallocate_frames, Frame};
|
||||||
|
use arch::paging::{entry, ActivePageTable, PhysicalAddress, VirtualAddress};
|
||||||
|
use context;
|
||||||
|
use context::memory::Grant;
|
||||||
|
use syscall::error::{Error, EFAULT, ENOMEM, EPERM, ESRCH, Result};
|
||||||
|
use syscall::flag::{MAP_WRITE, MAP_WRITE_COMBINE};
|
||||||
|
|
||||||
|
fn enforce_root() -> Result<()> {
|
||||||
|
let contexts = context::contexts();
|
||||||
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
let context = context_lock.read();
|
||||||
|
if context.euid == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(Error::new(EPERM))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iopl(_level: usize, _stack_base: usize) -> Result<usize> {
|
||||||
|
enforce_root()?;
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn physalloc(size: usize) -> Result<usize> {
|
||||||
|
enforce_root()?;
|
||||||
|
|
||||||
|
allocate_frames((size + 4095)/4096).ok_or(Error::new(ENOMEM)).map(|frame| frame.start_address().get())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn physfree(physical_address: usize, size: usize) -> Result<usize> {
|
||||||
|
enforce_root()?;
|
||||||
|
|
||||||
|
deallocate_frames(Frame::containing_address(PhysicalAddress::new(physical_address)), (size + 4095)/4096);
|
||||||
|
//TODO: Check that no double free occured
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: verify exlusive access to physical memory
|
||||||
|
pub fn physmap(physical_address: usize, size: usize, flags: usize) -> Result<usize> {
|
||||||
|
enforce_root()?;
|
||||||
|
|
||||||
|
if size == 0 {
|
||||||
|
Ok(0)
|
||||||
|
} else {
|
||||||
|
let contexts = context::contexts();
|
||||||
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
let context = context_lock.read();
|
||||||
|
|
||||||
|
let mut grants = context.grants.lock();
|
||||||
|
|
||||||
|
let from_address = (physical_address/4096) * 4096;
|
||||||
|
let offset = physical_address - from_address;
|
||||||
|
let full_size = ((offset + size + 4095)/4096) * 4096;
|
||||||
|
let mut to_address = arch::USER_GRANT_OFFSET;
|
||||||
|
|
||||||
|
let mut entry_flags = entry::PRESENT | entry::NO_EXECUTE | entry::USER_ACCESSIBLE;
|
||||||
|
if flags & MAP_WRITE == MAP_WRITE {
|
||||||
|
entry_flags |= entry::WRITABLE;
|
||||||
|
}
|
||||||
|
if flags & MAP_WRITE_COMBINE == MAP_WRITE_COMBINE {
|
||||||
|
entry_flags |= entry::HUGE_PAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0 .. grants.len() {
|
||||||
|
let start = grants[i].start_address().get();
|
||||||
|
if to_address + full_size < start {
|
||||||
|
grants.insert(i, Grant::physmap(
|
||||||
|
PhysicalAddress::new(from_address),
|
||||||
|
VirtualAddress::new(to_address),
|
||||||
|
full_size,
|
||||||
|
entry_flags
|
||||||
|
));
|
||||||
|
|
||||||
|
return Ok(to_address + offset);
|
||||||
|
} else {
|
||||||
|
let pages = (grants[i].size() + 4095) / 4096;
|
||||||
|
let end = start + pages * 4096;
|
||||||
|
to_address = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grants.push(Grant::physmap(
|
||||||
|
PhysicalAddress::new(from_address),
|
||||||
|
VirtualAddress::new(to_address),
|
||||||
|
full_size,
|
||||||
|
entry_flags
|
||||||
|
));
|
||||||
|
|
||||||
|
Ok(to_address + offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn physunmap(virtual_address: usize) -> Result<usize> {
|
||||||
|
enforce_root()?;
|
||||||
|
|
||||||
|
if virtual_address == 0 {
|
||||||
|
Ok(0)
|
||||||
|
} else {
|
||||||
|
let contexts = context::contexts();
|
||||||
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
let context = context_lock.read();
|
||||||
|
|
||||||
|
let mut grants = context.grants.lock();
|
||||||
|
|
||||||
|
for i in 0 .. grants.len() {
|
||||||
|
let start = grants[i].start_address().get();
|
||||||
|
let end = start + grants[i].size();
|
||||||
|
if virtual_address >= start && virtual_address < end {
|
||||||
|
grants.remove(i).unmap();
|
||||||
|
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(Error::new(EFAULT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn virttophys(virtual_address: usize) -> Result<usize> {
|
||||||
|
enforce_root()?;
|
||||||
|
|
||||||
|
let active_table = unsafe { ActivePageTable::new() };
|
||||||
|
match active_table.translate(VirtualAddress::new(virtual_address)) {
|
||||||
|
Some(physical_address) => Ok(physical_address.get()),
|
||||||
|
None => Err(Error::new(EFAULT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,8 +4,10 @@ extern crate syscall;
|
||||||
|
|
||||||
pub use self::syscall::{data, error, flag, number, scheme};
|
pub use self::syscall::{data, error, flag, number, scheme};
|
||||||
|
|
||||||
|
pub use self::driver::*;
|
||||||
pub use self::fs::*;
|
pub use self::fs::*;
|
||||||
pub use self::futex::futex;
|
pub use self::futex::futex;
|
||||||
|
pub use self::privilege::*;
|
||||||
pub use self::process::*;
|
pub use self::process::*;
|
||||||
pub use self::time::*;
|
pub use self::time::*;
|
||||||
pub use self::validate::*;
|
pub use self::validate::*;
|
||||||
|
|
@ -17,12 +19,18 @@ use self::number::*;
|
||||||
use context::ContextId;
|
use context::ContextId;
|
||||||
use scheme::FileHandle;
|
use scheme::FileHandle;
|
||||||
|
|
||||||
|
/// Driver syscalls
|
||||||
|
pub mod driver;
|
||||||
|
|
||||||
/// Filesystem syscalls
|
/// Filesystem syscalls
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
|
|
||||||
/// Fast userspace mutex
|
/// Fast userspace mutex
|
||||||
pub mod futex;
|
pub mod futex;
|
||||||
|
|
||||||
|
/// Privilege syscalls
|
||||||
|
pub mod privilege;
|
||||||
|
|
||||||
/// Process syscalls
|
/// Process syscalls
|
||||||
pub mod process;
|
pub mod process;
|
||||||
|
|
||||||
|
|
@ -65,13 +73,14 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
|
||||||
SYS_CLOCK_GETTIME => clock_gettime(b, validate_slice_mut(c as *mut TimeSpec, 1).map(|time| &mut time[0])?),
|
SYS_CLOCK_GETTIME => clock_gettime(b, validate_slice_mut(c as *mut TimeSpec, 1).map(|time| &mut time[0])?),
|
||||||
SYS_FUTEX => futex(validate_slice_mut(b as *mut i32, 1).map(|uaddr| &mut uaddr[0])?, c, d as i32, e, f as *mut i32),
|
SYS_FUTEX => futex(validate_slice_mut(b as *mut i32, 1).map(|uaddr| &mut uaddr[0])?, c, d as i32, e, f as *mut i32),
|
||||||
SYS_BRK => brk(b),
|
SYS_BRK => brk(b),
|
||||||
SYS_EXIT => exit(b),
|
|
||||||
SYS_WAITPID => waitpid(ContextId::from(b), c, d).map(ContextId::into),
|
|
||||||
SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?),
|
|
||||||
SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?),
|
|
||||||
SYS_GETPID => getpid().map(ContextId::into),
|
SYS_GETPID => getpid().map(ContextId::into),
|
||||||
SYS_IOPL => iopl(b),
|
|
||||||
SYS_CLONE => clone(b, stack).map(ContextId::into),
|
SYS_CLONE => clone(b, stack).map(ContextId::into),
|
||||||
|
SYS_EXIT => exit((b & 0xFF) << 8),
|
||||||
|
SYS_KILL => kill(ContextId::from(b), c),
|
||||||
|
SYS_WAITPID => waitpid(ContextId::from(b), c, d).map(ContextId::into),
|
||||||
|
SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?),
|
||||||
|
SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?),
|
||||||
|
SYS_IOPL => iopl(b, stack),
|
||||||
SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
|
SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
|
||||||
SYS_GETUID => getuid(),
|
SYS_GETUID => getuid(),
|
||||||
SYS_GETGID => getgid(),
|
SYS_GETGID => getgid(),
|
||||||
|
|
|
||||||
85
kernel/syscall/privilege.rs
Normal file
85
kernel/syscall/privilege.rs
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
use collections::Vec;
|
||||||
|
|
||||||
|
use context;
|
||||||
|
use scheme;
|
||||||
|
use syscall::error::*;
|
||||||
|
use syscall::validate::validate_slice;
|
||||||
|
|
||||||
|
pub fn getegid() -> Result<usize> {
|
||||||
|
let contexts = context::contexts();
|
||||||
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
let context = context_lock.read();
|
||||||
|
Ok(context.egid as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn geteuid() -> Result<usize> {
|
||||||
|
let contexts = context::contexts();
|
||||||
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
let context = context_lock.read();
|
||||||
|
Ok(context.euid as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getgid() -> Result<usize> {
|
||||||
|
let contexts = context::contexts();
|
||||||
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
let context = context_lock.read();
|
||||||
|
Ok(context.rgid as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getuid() -> Result<usize> {
|
||||||
|
let contexts = context::contexts();
|
||||||
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
let context = context_lock.read();
|
||||||
|
Ok(context.ruid as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setgid(gid: u32) -> Result<usize> {
|
||||||
|
let contexts = context::contexts();
|
||||||
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
let mut context = context_lock.write();
|
||||||
|
if context.egid == 0 {
|
||||||
|
context.rgid = gid;
|
||||||
|
context.egid = gid;
|
||||||
|
Ok(0)
|
||||||
|
} else {
|
||||||
|
Err(Error::new(EPERM))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setuid(uid: u32) -> Result<usize> {
|
||||||
|
let contexts = context::contexts();
|
||||||
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
let mut context = context_lock.write();
|
||||||
|
if context.euid == 0 {
|
||||||
|
context.ruid = uid;
|
||||||
|
context.euid = uid;
|
||||||
|
Ok(0)
|
||||||
|
} else {
|
||||||
|
Err(Error::new(EPERM))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setns(name_ptrs: &[[usize; 2]]) -> Result<usize> {
|
||||||
|
let mut names = Vec::new();
|
||||||
|
for name_ptr in name_ptrs {
|
||||||
|
names.push(validate_slice(name_ptr[0] as *const u8, name_ptr[1])?);
|
||||||
|
}
|
||||||
|
|
||||||
|
let from = {
|
||||||
|
let contexts = context::contexts();
|
||||||
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
let context = context_lock.read();
|
||||||
|
context.scheme_ns
|
||||||
|
};
|
||||||
|
|
||||||
|
let to = scheme::schemes_mut().setns(from, &names)?;
|
||||||
|
|
||||||
|
{
|
||||||
|
let contexts = context::contexts();
|
||||||
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
let mut context = context_lock.write();
|
||||||
|
context.scheme_ns = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
@ -7,19 +7,18 @@ use core::ops::DerefMut;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
use arch;
|
use arch;
|
||||||
use arch::memory::{allocate_frame, allocate_frames, deallocate_frames, Frame};
|
use arch::memory::allocate_frame;
|
||||||
use arch::paging::{ActivePageTable, InactivePageTable, Page, PhysicalAddress, VirtualAddress, entry};
|
use arch::paging::{ActivePageTable, InactivePageTable, Page, VirtualAddress, entry};
|
||||||
use arch::paging::temporary_page::TemporaryPage;
|
use arch::paging::temporary_page::TemporaryPage;
|
||||||
use arch::start::usermode;
|
use arch::start::usermode;
|
||||||
use context;
|
use context;
|
||||||
use context::ContextId;
|
use context::ContextId;
|
||||||
use context::memory::Grant;
|
|
||||||
use elf::{self, program_header};
|
use elf::{self, program_header};
|
||||||
use scheme::{self, FileHandle};
|
use scheme::{self, FileHandle};
|
||||||
use syscall;
|
use syscall;
|
||||||
use syscall::data::Stat;
|
use syscall::data::Stat;
|
||||||
use syscall::error::*;
|
use syscall::error::*;
|
||||||
use syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, MAP_WRITE, MAP_WRITE_COMBINE, WNOHANG};
|
use syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, WNOHANG};
|
||||||
use syscall::validate::{validate_slice, validate_slice_mut};
|
use syscall::validate::{validate_slice, validate_slice_mut};
|
||||||
|
|
||||||
pub fn brk(address: usize) -> Result<usize> {
|
pub fn brk(address: usize) -> Result<usize> {
|
||||||
|
|
@ -838,27 +837,6 @@ pub fn exit(status: usize) -> ! {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getegid() -> Result<usize> {
|
|
||||||
let contexts = context::contexts();
|
|
||||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
|
||||||
let context = context_lock.read();
|
|
||||||
Ok(context.egid as usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn geteuid() -> Result<usize> {
|
|
||||||
let contexts = context::contexts();
|
|
||||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
|
||||||
let context = context_lock.read();
|
|
||||||
Ok(context.euid as usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getgid() -> Result<usize> {
|
|
||||||
let contexts = context::contexts();
|
|
||||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
|
||||||
let context = context_lock.read();
|
|
||||||
Ok(context.rgid as usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getpid() -> Result<ContextId> {
|
pub fn getpid() -> Result<ContextId> {
|
||||||
let contexts = context::contexts();
|
let contexts = context::contexts();
|
||||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
|
@ -866,224 +844,29 @@ pub fn getpid() -> Result<ContextId> {
|
||||||
Ok(context.id)
|
Ok(context.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getuid() -> Result<usize> {
|
|
||||||
let contexts = context::contexts();
|
|
||||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
|
||||||
let context = context_lock.read();
|
|
||||||
Ok(context.ruid as usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iopl(_level: usize) -> Result<usize> {
|
|
||||||
//TODO
|
|
||||||
Ok(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
|
pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
|
||||||
use syscall::flag::*;
|
let (ruid, euid) = {
|
||||||
|
let contexts = context::contexts();
|
||||||
|
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||||
|
let context = context_lock.read();
|
||||||
|
(context.ruid, context.euid)
|
||||||
|
};
|
||||||
|
|
||||||
let _context_lock = {
|
if sig > 0 && sig <= 0x7F {
|
||||||
let contexts = context::contexts();
|
let contexts = context::contexts();
|
||||||
let context_lock = contexts.get(pid).ok_or(Error::new(ESRCH))?;
|
let context_lock = contexts.get(pid).ok_or(Error::new(ESRCH))?;
|
||||||
context_lock.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
let term = || {
|
|
||||||
println!("Terminate {:?}", pid);
|
|
||||||
};
|
|
||||||
|
|
||||||
let core = || {
|
|
||||||
println!("Core {:?}", pid);
|
|
||||||
};
|
|
||||||
|
|
||||||
let stop = || {
|
|
||||||
println!("Stop {:?}", pid);
|
|
||||||
};
|
|
||||||
|
|
||||||
let cont = || {
|
|
||||||
println!("Continue {:?}", pid);
|
|
||||||
};
|
|
||||||
|
|
||||||
match sig {
|
|
||||||
0 => (),
|
|
||||||
SIGHUP => term(),
|
|
||||||
SIGINT => term(),
|
|
||||||
SIGQUIT => core(),
|
|
||||||
SIGILL => core(),
|
|
||||||
SIGTRAP => core(),
|
|
||||||
SIGABRT => core(),
|
|
||||||
SIGBUS => core(),
|
|
||||||
SIGFPE => core(),
|
|
||||||
SIGKILL => term(),
|
|
||||||
SIGUSR1 => term(),
|
|
||||||
SIGSEGV => core(),
|
|
||||||
SIGPIPE => term(),
|
|
||||||
SIGALRM => term(),
|
|
||||||
SIGTERM => term(),
|
|
||||||
SIGSTKFLT => term(),
|
|
||||||
SIGCHLD => (),
|
|
||||||
SIGCONT => cont(),
|
|
||||||
SIGSTOP => stop(),
|
|
||||||
SIGTSTP => stop(),
|
|
||||||
SIGTTIN => stop(),
|
|
||||||
SIGTTOU => stop(),
|
|
||||||
SIGURG => (),
|
|
||||||
SIGXCPU => core(),
|
|
||||||
SIGXFSZ => core(),
|
|
||||||
SIGVTALRM => term(),
|
|
||||||
SIGPROF => term(),
|
|
||||||
SIGWINCH => (),
|
|
||||||
SIGIO => term(),
|
|
||||||
SIGPWR => term(),
|
|
||||||
SIGSYS => core(),
|
|
||||||
_ => return Err(Error::new(EINVAL))
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn physalloc(size: usize) -> Result<usize> {
|
|
||||||
allocate_frames((size + 4095)/4096).ok_or(Error::new(ENOMEM)).map(|frame| frame.start_address().get())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn physfree(physical_address: usize, size: usize) -> Result<usize> {
|
|
||||||
deallocate_frames(Frame::containing_address(PhysicalAddress::new(physical_address)), (size + 4095)/4096);
|
|
||||||
//TODO: Check that no double free occured
|
|
||||||
Ok(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: verify exlusive access to physical memory
|
|
||||||
pub fn physmap(physical_address: usize, size: usize, flags: usize) -> Result<usize> {
|
|
||||||
if size == 0 {
|
|
||||||
Ok(0)
|
|
||||||
} else {
|
|
||||||
let contexts = context::contexts();
|
|
||||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
|
||||||
let context = context_lock.read();
|
|
||||||
|
|
||||||
let mut grants = context.grants.lock();
|
|
||||||
|
|
||||||
let from_address = (physical_address/4096) * 4096;
|
|
||||||
let offset = physical_address - from_address;
|
|
||||||
let full_size = ((offset + size + 4095)/4096) * 4096;
|
|
||||||
let mut to_address = arch::USER_GRANT_OFFSET;
|
|
||||||
|
|
||||||
let mut entry_flags = entry::PRESENT | entry::NO_EXECUTE | entry::USER_ACCESSIBLE;
|
|
||||||
if flags & MAP_WRITE == MAP_WRITE {
|
|
||||||
entry_flags |= entry::WRITABLE;
|
|
||||||
}
|
|
||||||
if flags & MAP_WRITE_COMBINE == MAP_WRITE_COMBINE {
|
|
||||||
entry_flags |= entry::HUGE_PAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for i in 0 .. grants.len() {
|
|
||||||
let start = grants[i].start_address().get();
|
|
||||||
if to_address + full_size < start {
|
|
||||||
grants.insert(i, Grant::physmap(
|
|
||||||
PhysicalAddress::new(from_address),
|
|
||||||
VirtualAddress::new(to_address),
|
|
||||||
full_size,
|
|
||||||
entry_flags
|
|
||||||
));
|
|
||||||
|
|
||||||
return Ok(to_address + offset);
|
|
||||||
} else {
|
|
||||||
let pages = (grants[i].size() + 4095) / 4096;
|
|
||||||
let end = start + pages * 4096;
|
|
||||||
to_address = end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
grants.push(Grant::physmap(
|
|
||||||
PhysicalAddress::new(from_address),
|
|
||||||
VirtualAddress::new(to_address),
|
|
||||||
full_size,
|
|
||||||
entry_flags
|
|
||||||
));
|
|
||||||
|
|
||||||
Ok(to_address + offset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn physunmap(virtual_address: usize) -> Result<usize> {
|
|
||||||
if virtual_address == 0 {
|
|
||||||
Ok(0)
|
|
||||||
} else {
|
|
||||||
let contexts = context::contexts();
|
|
||||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
|
||||||
let context = context_lock.read();
|
|
||||||
|
|
||||||
let mut grants = context.grants.lock();
|
|
||||||
|
|
||||||
for i in 0 .. grants.len() {
|
|
||||||
let start = grants[i].start_address().get();
|
|
||||||
let end = start + grants[i].size();
|
|
||||||
if virtual_address >= start && virtual_address < end {
|
|
||||||
grants.remove(i).unmap();
|
|
||||||
|
|
||||||
return Ok(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(Error::new(EFAULT))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn setgid(gid: u32) -> Result<usize> {
|
|
||||||
let contexts = context::contexts();
|
|
||||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
|
||||||
let mut context = context_lock.write();
|
|
||||||
if context.egid == 0 {
|
|
||||||
context.rgid = gid;
|
|
||||||
context.egid = gid;
|
|
||||||
Ok(0)
|
|
||||||
} else {
|
|
||||||
Err(Error::new(EPERM))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn setuid(uid: u32) -> Result<usize> {
|
|
||||||
let contexts = context::contexts();
|
|
||||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
|
||||||
let mut context = context_lock.write();
|
|
||||||
if context.euid == 0 {
|
|
||||||
context.ruid = uid;
|
|
||||||
context.euid = uid;
|
|
||||||
Ok(0)
|
|
||||||
} else {
|
|
||||||
Err(Error::new(EPERM))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn setns(name_ptrs: &[[usize; 2]]) -> Result<usize> {
|
|
||||||
let mut names = Vec::new();
|
|
||||||
for name_ptr in name_ptrs {
|
|
||||||
names.push(validate_slice(name_ptr[0] as *const u8, name_ptr[1])?);
|
|
||||||
}
|
|
||||||
|
|
||||||
let from = {
|
|
||||||
let contexts = context::contexts();
|
|
||||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
|
||||||
let context = context_lock.read();
|
|
||||||
context.scheme_ns
|
|
||||||
};
|
|
||||||
|
|
||||||
let to = scheme::schemes_mut().setns(from, &names)?;
|
|
||||||
|
|
||||||
{
|
|
||||||
let contexts = context::contexts();
|
|
||||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
|
||||||
let mut context = context_lock.write();
|
let mut context = context_lock.write();
|
||||||
context.scheme_ns = to;
|
if euid == 0
|
||||||
}
|
|| euid == context.ruid
|
||||||
|
|| ruid == context.ruid
|
||||||
Ok(0)
|
{
|
||||||
}
|
context.pending.push_back(sig as u8);
|
||||||
|
Ok(0)
|
||||||
pub fn virttophys(virtual_address: usize) -> Result<usize> {
|
} else {
|
||||||
let active_table = unsafe { ActivePageTable::new() };
|
Err(Error::new(EPERM))
|
||||||
match active_table.translate(VirtualAddress::new(virtual_address)) {
|
}
|
||||||
Some(physical_address) => Ok(physical_address.get()),
|
} else {
|
||||||
None => Err(Error::new(EFAULT))
|
Err(Error::new(EINVAL))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
1
libstd
1
libstd
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 18d61d7e8a469fb0a05a9db4d00970b7e45954ad
|
|
||||||
19
libstd/Cargo.toml
Normal file
19
libstd/Cargo.toml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
[package]
|
||||||
|
name = "redox_std"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "std"
|
||||||
|
path = "../rust/src/libstd/lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
alloc_system = { path = "alloc_system" }
|
||||||
|
compiler_builtins = { path = "compiler_builtins" }
|
||||||
|
panic_abort = { path = "panic_abort" }
|
||||||
|
#panic_unwind = { path = "panic_unwind" }
|
||||||
|
libc = { path = "libc" }
|
||||||
|
unwind = { path = "unwind" }
|
||||||
|
|
||||||
|
[replace]
|
||||||
|
"libc:0.2.17" = { git = "https://github.com/rust-lang/libc.git" }
|
||||||
13
libstd/alloc_system/Cargo.toml
Normal file
13
libstd/alloc_system/Cargo.toml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "alloc_system"
|
||||||
|
version = "0.0.0"
|
||||||
|
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||||
|
|
||||||
|
[dependencies.ralloc]
|
||||||
|
git = "https://github.com/redox-os/ralloc.git"
|
||||||
|
branch = "new_kernel"
|
||||||
|
default-features = false
|
||||||
|
features = ["allocator"]
|
||||||
|
|
||||||
|
[replace]
|
||||||
|
"libc:0.2.17" = { git = "https://github.com/rust-lang/libc.git" }
|
||||||
6
libstd/alloc_system/src/lib.rs
Normal file
6
libstd/alloc_system/src/lib.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#![allocator]
|
||||||
|
#![feature(allocator)]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
#[allocator]
|
||||||
|
extern crate ralloc;
|
||||||
4
libstd/compiler_builtins/Cargo.toml
Normal file
4
libstd/compiler_builtins/Cargo.toml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
[package]
|
||||||
|
name = "compiler_builtins"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||||
72
libstd/compiler_builtins/src/lib.rs
Normal file
72
libstd/compiler_builtins/src/lib.rs
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
/// Memcpy
|
||||||
|
///
|
||||||
|
/// Copy N bytes of memory from one location to another.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8,
|
||||||
|
n: usize) -> *mut u8 {
|
||||||
|
let mut i = 0;
|
||||||
|
while i < n {
|
||||||
|
*((dest as usize + i) as *mut u8) = *((src as usize + i) as *const u8);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Memmove
|
||||||
|
///
|
||||||
|
/// Copy N bytes of memory from src to dest. The memory areas may overlap.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn memmove(dest: *mut u8, src: *const u8,
|
||||||
|
n: usize) -> *mut u8 {
|
||||||
|
if src < dest as *const u8 {
|
||||||
|
let mut i = n;
|
||||||
|
while i != 0 {
|
||||||
|
i -= 1;
|
||||||
|
*((dest as usize + i) as *mut u8) = *((src as usize + i) as *const u8);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut i = 0;
|
||||||
|
while i < n {
|
||||||
|
*((dest as usize + i) as *mut u8) = *((src as usize + i) as *const u8);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dest
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Memset
|
||||||
|
///
|
||||||
|
/// Fill a block of memory with a specified value.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn memset(dest: *mut u8, c: i32, n: usize) -> *mut u8 {
|
||||||
|
let mut i = 0;
|
||||||
|
while i < n {
|
||||||
|
*((dest as usize + i) as *mut u8) = c as u8;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Memcmp
|
||||||
|
///
|
||||||
|
/// Compare two blocks of memory.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
|
||||||
|
let mut i = 0;
|
||||||
|
|
||||||
|
while i < n {
|
||||||
|
let a = *((s1 as usize + i) as *const u8);
|
||||||
|
let b = *((s2 as usize + i) as *const u8);
|
||||||
|
if a != b {
|
||||||
|
return a as i32 - b as i32
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
||||||
9
libstd/libc/Cargo.toml
Normal file
9
libstd/libc/Cargo.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
redox_syscall = { path = "../../syscall/" }
|
||||||
|
spin = "*"
|
||||||
18
libstd/libc/build.rs
Normal file
18
libstd/libc/build.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![deny(warnings)]
|
||||||
|
|
||||||
|
// See comments in Cargo.toml for why this exists
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("cargo:rustc-cfg=stdbuild");
|
||||||
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
}
|
||||||
40
libstd/libc/src/funcs.rs
Normal file
40
libstd/libc/src/funcs.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
use super::{c_char, size_t};
|
||||||
|
|
||||||
|
pub unsafe extern fn strlen(ptr: *const c_char) -> size_t {
|
||||||
|
let mut i: size_t = 0;
|
||||||
|
while *ptr.offset(i as isize) != 0 {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
i
|
||||||
|
}
|
||||||
|
|
||||||
|
extern crate spin;
|
||||||
|
use core::cell::Cell;
|
||||||
|
use self::spin::Mutex;
|
||||||
|
|
||||||
|
/// The randomness state.
|
||||||
|
///
|
||||||
|
/// This is updated when a new random integer is read.
|
||||||
|
static STATE: Mutex<[u64; 2]> = Mutex::new([0xBADF00D1, 0xDEADBEEF]);
|
||||||
|
|
||||||
|
/// Get a pseudorandom integer.
|
||||||
|
///
|
||||||
|
/// Note that this is full-cycle, so apply a modulo when true equidistribution is needed.
|
||||||
|
pub unsafe extern fn random() -> u64 {
|
||||||
|
// Fetch the state.
|
||||||
|
let mut state = STATE.lock();
|
||||||
|
|
||||||
|
// Store the first and second part.
|
||||||
|
let mut x = state[0];
|
||||||
|
let y = state[1];
|
||||||
|
|
||||||
|
// Put the second part into the first slot.
|
||||||
|
state[0] = y;
|
||||||
|
// Twist the first slot.
|
||||||
|
x ^= x << 23;
|
||||||
|
// Update the second slot.
|
||||||
|
state[1] = x ^ y ^ (x >> 17) ^ (y >> 26);
|
||||||
|
|
||||||
|
// Generate the final integer.
|
||||||
|
state[1].wrapping_add(y)
|
||||||
|
}
|
||||||
28
libstd/libc/src/lib.rs
Normal file
28
libstd/libc/src/lib.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#![no_std]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
#![feature(asm)]
|
||||||
|
#![feature(const_fn)]
|
||||||
|
#![feature(naked_functions)]
|
||||||
|
#![feature(thread_local)]
|
||||||
|
|
||||||
|
#![cfg_attr(stdbuild, feature(no_std, core, core_slice_ext, staged_api, custom_attribute, cfg_target_vendor))]
|
||||||
|
#![cfg_attr(stdbuild, no_std)]
|
||||||
|
#![cfg_attr(stdbuild, staged_api)]
|
||||||
|
#![cfg_attr(stdbuild, allow(warnings))]
|
||||||
|
#![cfg_attr(stdbuild, unstable(feature = "libc",
|
||||||
|
reason = "use `libc` from crates.io",
|
||||||
|
issue = "27783"))]
|
||||||
|
|
||||||
|
pub use types::*;
|
||||||
|
pub use funcs::*;
|
||||||
|
pub use start::*;
|
||||||
|
pub use syscall::*;
|
||||||
|
|
||||||
|
/// Basic types (not usually system specific)
|
||||||
|
mod types;
|
||||||
|
/// Basic functions (not system specific)
|
||||||
|
mod funcs;
|
||||||
|
/// Start function and call in to libstd
|
||||||
|
mod start;
|
||||||
|
/// Conversion for syscall library (specific to Redox)
|
||||||
|
mod syscall;
|
||||||
40
libstd/libc/src/start.rs
Normal file
40
libstd/libc/src/start.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
use super::exit;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[naked]
|
||||||
|
#[cfg(target_arch = "x86")]
|
||||||
|
pub unsafe fn _start() {
|
||||||
|
asm!("push esp
|
||||||
|
call _start_stack
|
||||||
|
pop esp"
|
||||||
|
:
|
||||||
|
:
|
||||||
|
: "memory"
|
||||||
|
: "intel", "volatile");
|
||||||
|
let _ = exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[naked]
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
pub unsafe fn _start() {
|
||||||
|
asm!("mov rdi, rsp
|
||||||
|
and rsp, 0xFFFFFFFFFFFFFFF0
|
||||||
|
call _start_stack"
|
||||||
|
:
|
||||||
|
:
|
||||||
|
: "memory"
|
||||||
|
: "intel", "volatile");
|
||||||
|
let _ = exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn _start_stack(stack: *const usize){
|
||||||
|
extern "C" {
|
||||||
|
fn main(argc: usize, argv: *const *const u8) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
let argc = *stack as usize;
|
||||||
|
let argv = stack.offset(1) as *const *const u8;
|
||||||
|
let _ = exit(main(argc, argv));
|
||||||
|
}
|
||||||
83
libstd/libc/src/syscall.rs
Normal file
83
libstd/libc/src/syscall.rs
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
/// Convert syscall types to libc types
|
||||||
|
extern crate syscall;
|
||||||
|
|
||||||
|
use super::{c_int, sa_family_t};
|
||||||
|
|
||||||
|
use self::syscall::data::{Stat, TimeSpec};
|
||||||
|
|
||||||
|
pub use self::syscall::error::*;
|
||||||
|
pub use self::syscall::flag::*;
|
||||||
|
pub use self::syscall::{
|
||||||
|
clock_gettime, clone, execve as exec, exit, futex, getpid, kill, nanosleep, setgid, setuid, waitpid,
|
||||||
|
chdir, chmod, getcwd, open, mkdir, rmdir, unlink, dup, pipe2,
|
||||||
|
read, write, fcntl, fpath, fstat, fsync, ftruncate, lseek, close
|
||||||
|
};
|
||||||
|
|
||||||
|
//TODO: Thread local
|
||||||
|
pub static mut errno: c_int = 0;
|
||||||
|
|
||||||
|
pub type stat = Stat;
|
||||||
|
pub type timespec = TimeSpec;
|
||||||
|
|
||||||
|
pub const AF_INET: sa_family_t = 1;
|
||||||
|
pub const AF_INET6: sa_family_t = 2;
|
||||||
|
|
||||||
|
pub const STDIN_FILENO: usize = 0;
|
||||||
|
pub const STDOUT_FILENO: usize = 1;
|
||||||
|
pub const STDERR_FILENO: usize = 2;
|
||||||
|
|
||||||
|
fn cvt(result: syscall::Result<usize>) -> c_int {
|
||||||
|
match result {
|
||||||
|
Ok(res) => res as c_int,
|
||||||
|
Err(err) => {
|
||||||
|
unsafe { errno = err.errno };
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ralloc shims {
|
||||||
|
/// Cooperatively gives up a timeslice to the OS scheduler.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn sched_yield() -> c_int {
|
||||||
|
cvt(syscall::sched_yield())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Increment data segment of this process by some, _n_, return a pointer to the new data segment
|
||||||
|
/// start.
|
||||||
|
///
|
||||||
|
/// This uses the system call BRK as backend.
|
||||||
|
///
|
||||||
|
/// This is unsafe for multiple reasons. Most importantly, it can create an inconsistent state,
|
||||||
|
/// because it is not atomic. Thus, it can be used to create Undefined Behavior.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn sbrk(n: isize) -> *mut u8 {
|
||||||
|
let orig_seg_end = match unsafe { syscall::brk(0) } {
|
||||||
|
Ok(end) => end,
|
||||||
|
Err(_) => return !0 as *mut u8
|
||||||
|
};
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
return orig_seg_end as *mut u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
let expected_end = match orig_seg_end.checked_add(n as usize) {
|
||||||
|
Some(end) => end,
|
||||||
|
None => return !0 as *mut u8
|
||||||
|
};
|
||||||
|
|
||||||
|
let new_seg_end = match unsafe { syscall::brk(expected_end) } {
|
||||||
|
Ok(end) => end,
|
||||||
|
Err(_) => return !0 as *mut u8
|
||||||
|
};
|
||||||
|
|
||||||
|
if new_seg_end != expected_end {
|
||||||
|
// Reset the break.
|
||||||
|
let _ = unsafe { syscall::brk(orig_seg_end) };
|
||||||
|
|
||||||
|
!0 as *mut u8
|
||||||
|
} else {
|
||||||
|
orig_seg_end as *mut u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// } ralloc shims
|
||||||
96
libstd/libc/src/types.rs
Normal file
96
libstd/libc/src/types.rs
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
|
||||||
|
// more optimization opportunities around it recognizing things like
|
||||||
|
// malloc/free.
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum c_void {
|
||||||
|
// Two dummy variants so the #[repr] attribute can be used.
|
||||||
|
#[doc(hidden)]
|
||||||
|
__variant1,
|
||||||
|
#[doc(hidden)]
|
||||||
|
__variant2,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type int8_t = i8;
|
||||||
|
pub type int16_t = i16;
|
||||||
|
pub type int32_t = i32;
|
||||||
|
pub type int64_t = i64;
|
||||||
|
pub type uint8_t = u8;
|
||||||
|
pub type uint16_t = u16;
|
||||||
|
pub type uint32_t = u32;
|
||||||
|
pub type uint64_t = u64;
|
||||||
|
|
||||||
|
pub type c_schar = i8;
|
||||||
|
pub type c_uchar = u8;
|
||||||
|
pub type c_short = i16;
|
||||||
|
pub type c_ushort = u16;
|
||||||
|
pub type c_float = f32;
|
||||||
|
pub type c_double = f64;
|
||||||
|
|
||||||
|
pub type intmax_t = i64;
|
||||||
|
pub type uintmax_t = u64;
|
||||||
|
|
||||||
|
pub type c_char = i8;
|
||||||
|
pub type c_int = i32;
|
||||||
|
pub type c_uint = u32;
|
||||||
|
pub type c_long = i64;
|
||||||
|
pub type c_ulong = u64;
|
||||||
|
pub type c_longlong = i64;
|
||||||
|
pub type c_ulonglong = u64;
|
||||||
|
|
||||||
|
pub type off_t = usize;
|
||||||
|
pub type size_t = usize;
|
||||||
|
pub type ptrdiff_t = isize;
|
||||||
|
pub type intptr_t = isize;
|
||||||
|
pub type uintptr_t = usize;
|
||||||
|
pub type ssize_t = isize;
|
||||||
|
|
||||||
|
pub type mode_t = u16;
|
||||||
|
pub type time_t = i64;
|
||||||
|
pub type pid_t = usize;
|
||||||
|
pub type gid_t = usize;
|
||||||
|
pub type uid_t = usize;
|
||||||
|
|
||||||
|
pub type in_addr_t = u32;
|
||||||
|
pub type in_port_t = u16;
|
||||||
|
|
||||||
|
pub type socklen_t = u32;
|
||||||
|
pub type sa_family_t = u16;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct in_addr {
|
||||||
|
pub s_addr: in_addr_t,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct in6_addr {
|
||||||
|
pub s6_addr: [u8; 16],
|
||||||
|
__align: [u32; 0],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct sockaddr {
|
||||||
|
pub sa_family: sa_family_t,
|
||||||
|
pub sa_data: [::c_char; 14],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct sockaddr_in {
|
||||||
|
pub sin_family: sa_family_t,
|
||||||
|
pub sin_port: ::in_port_t,
|
||||||
|
pub sin_addr: ::in_addr,
|
||||||
|
pub sin_zero: [u8; 8],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct sockaddr_in6 {
|
||||||
|
pub sin6_family: sa_family_t,
|
||||||
|
pub sin6_port: in_port_t,
|
||||||
|
pub sin6_flowinfo: u32,
|
||||||
|
pub sin6_addr: ::in6_addr,
|
||||||
|
pub sin6_scope_id: u32,
|
||||||
|
}
|
||||||
1
libstd/openlibm
Submodule
1
libstd/openlibm
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 3c837e79655c4be724efb945a6345ec97c07635c
|
||||||
10
libstd/panic_abort/Cargo.toml
Normal file
10
libstd/panic_abort/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "panic_abort"
|
||||||
|
version = "0.0.0"
|
||||||
|
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "../../rust/src/libpanic_abort/lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
redox_syscall = { path = "../../syscall/" }
|
||||||
12
libstd/panic_unwind/Cargo.toml
Normal file
12
libstd/panic_unwind/Cargo.toml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "panic_unwind"
|
||||||
|
version = "0.0.0"
|
||||||
|
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "../../rust/src/libpanic_unwind/lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libc = { path = "../libc/" }
|
||||||
|
redox_syscall = { path = "../../syscall/" }
|
||||||
|
unwind = { path = "../unwind/" }
|
||||||
10
libstd/unwind/Cargo.toml
Normal file
10
libstd/unwind/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "unwind"
|
||||||
|
version = "0.0.0"
|
||||||
|
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "../../rust/src/libunwind/lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libc = { path = "../libc/" }
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue