Skip to content
Snippets Groups Projects
Commit fff607cf authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Cleanup of shims

parent 5be8d0bc
No related branches found
No related tags found
No related merge requests found
......@@ -2,7 +2,13 @@
name = "libc"
version = "0.1.0"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
build = "build.rs"
build = "../../rust/src/rustc/libc_shim/build.rs"
[lib]
name = "libc"
path = "../../rust/src/liblibc/src/lib.rs"
test = false
bench = false
[dependencies]
redox_syscall = { path = "../../syscall/" }
......
// 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");
}
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)
}
#![no_std]
#![allow(non_camel_case_types)]
#![feature(asm)]
#![feature(const_fn)]
#![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 syscall::*;
/// Basic types (not usually system specific)
mod types;
/// Basic functions (not system specific)
mod funcs;
/// Conversion for syscall library (specific to Redox)
mod syscall;
/// 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, setregid, setreuid, waitpid,
chdir, chmod, getcwd, open, 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
// 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,
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment