Add signal support - exit on signal

This commit is contained in:
Jeremy Soller 2016-11-17 12:12:02 -07:00
commit bf292bc0d1
31 changed files with 393 additions and 311 deletions

6
.gitmodules vendored
View file

@ -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

View file

@ -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 \

View file

@ -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");
}

View file

@ -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);
}); });

View file

@ -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,

View file

@ -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);
}

View file

@ -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
View 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))
}
}

View file

@ -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(),

View 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)
}

View file

@ -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 +0,0 @@
Subproject commit 18d61d7e8a469fb0a05a9db4d00970b7e45954ad

19
libstd/Cargo.toml Normal file
View 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" }

View 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" }

View file

@ -0,0 +1,6 @@
#![allocator]
#![feature(allocator)]
#![no_std]
#[allocator]
extern crate ralloc;

View file

@ -0,0 +1,4 @@
[package]
name = "compiler_builtins"
version = "0.1.0"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]

View 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
View 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
View 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
View 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
View 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
View 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));
}

View 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
View 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

@ -0,0 +1 @@
Subproject commit 3c837e79655c4be724efb945a6345ec97c07635c

View 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/" }

View 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
View 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