Commit 78e421cb authored by Jeremy Soller's avatar Jeremy Soller

Implement some functions on Linux

parent 9fb0b77d
This diff is collapsed.
......@@ -8,17 +8,16 @@ name = "c"
crate-type = ["staticlib"]
[workspace]
members = ["crt0"]
[dependencies]
compiler_builtins = { git = "https://github.com/rust-lang-nursery/compiler-builtins.git", default-features = false, features = ["mem"] }
platform = { path = "platform" }
fcntl = { path = "fcntl" }
unistd = { path = "unistd" }
[profile.dev]
incremental = false
lto = true
panic = "abort"
[profile.release]
incremental = false
lto = true
panic = "abort"
[package]
name = "crt0"
version = "0.1.0"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
[lib]
name = "crt0"
crate-type = ["staticlib"]
[dependencies]
platform = { path = "../platform" }
//! crt0
#![no_std]
#![feature(asm)]
#![feature(lang_items)]
#![feature(naked_functions)]
extern crate platform;
use platform::types::*;
#[no_mangle]
#[naked]
pub unsafe extern "C" fn _start() {
asm!("mov rdi, rsp
call _start_rust"
:
:
:
: "intel"
);
}
#[inline(never)]
#[no_mangle]
pub unsafe extern "C" fn _start_rust(sp: usize) -> ! {
extern "C" {
fn main(argc: c_int, argv: *const *const c_char) -> c_int;
}
platform::exit(main(0, 0 as *const *const c_char));
}
#[lang = "panic_fmt"]
pub extern "C" fn rust_begin_unwind(fmt: ::core::fmt::Arguments, file: &str, line: u32) -> ! {
loop {}
}
......@@ -8,4 +8,4 @@ build = "build.rs"
cbindgen = { path = "../cbindgen" }
[dependencies]
common = { path = "../common" }
platform = { path = "../platform" }
......@@ -2,9 +2,19 @@
#![no_std]
extern crate common;
extern crate platform;
pub use common::*;
use platform::types::*;
pub use sys::*;
#[cfg(target_os = "linux")]
#[path="linux.rs"]
pub mod sys;
#[cfg(target_os = "redox")]
#[path="redox.rs"]
pub mod sys;
pub const F_DUPFD: c_int = 0;
pub const F_GETFD: c_int = 1;
......@@ -21,25 +31,6 @@ pub const F_RDLCK: c_int = 0;
pub const F_WRLCK: c_int = 1;
pub const F_UNLCK: c_int = 2;
pub const O_RDONLY: c_int = 0x0001_0000;
pub const O_WRONLY: c_int = 0x0002_0000;
pub const O_RDWR: c_int = 0x0003_0000;
pub const O_NONBLOCK: c_int = 0x0004_0000;
pub const O_APPEND: c_int = 0x0008_0000;
pub const O_SHLOCK: c_int = 0x0010_0000;
pub const O_EXLOCK: c_int = 0x0020_0000;
pub const O_ASYNC: c_int = 0x0040_0000;
pub const O_FSYNC: c_int = 0x0080_0000;
pub const O_CLOEXEC: c_int = 0x0100_0000;
pub const O_CREAT: c_int = 0x0200_0000;
pub const O_TRUNC: c_int = 0x0400_0000;
pub const O_EXCL: c_int = 0x0800_0000;
pub const O_DIRECTORY: c_int = 0x1000_0000;
pub const O_STAT: c_int = 0x2000_0000;
pub const O_SYMLINK: c_int = 0x4000_0000;
pub const O_NOFOLLOW: c_int = 0x8000_0000;
pub const O_ACCMODE: c_int = O_RDONLY | O_WRONLY | O_RDWR;
#[no_mangle]
pub extern "C" fn creat(path: *const c_char, mode: mode_t) -> c_int {
open(path, O_WRONLY | O_CREAT | O_TRUNC, mode)
......@@ -52,7 +43,7 @@ pub extern "C" fn fcntl(fildes: c_int, cmd: c_int, arg: c_int) -> c_int {
#[no_mangle]
pub extern "C" fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
unimplemented!();
platform::open(path, oflag, mode)
}
/*
......
use platform::types::*;
pub const O_RDONLY: c_int = 0x0000;
pub const O_WRONLY: c_int = 0x0001;
pub const O_RDWR: c_int = 0x0002;
pub const O_CREAT: c_int = 0x0040;
pub const O_TRUNC: c_int = 0x0200;
pub const O_ACCMODE: c_int = O_RDONLY | O_WRONLY | O_RDWR;
use platform::types::*;
pub const O_RDONLY: c_int = 0x0001_0000;
pub const O_WRONLY: c_int = 0x0002_0000;
pub const O_RDWR: c_int = 0x0003_0000;
pub const O_NONBLOCK: c_int = 0x0004_0000;
pub const O_APPEND: c_int = 0x0008_0000;
pub const O_SHLOCK: c_int = 0x0010_0000;
pub const O_EXLOCK: c_int = 0x0020_0000;
pub const O_ASYNC: c_int = 0x0040_0000;
pub const O_FSYNC: c_int = 0x0080_0000;
pub const O_CLOEXEC: c_int = 0x0100_0000;
pub const O_CREAT: c_int = 0x0200_0000;
pub const O_TRUNC: c_int = 0x0400_0000;
pub const O_EXCL: c_int = 0x0800_0000;
pub const O_DIRECTORY: c_int = 0x1000_0000;
pub const O_STAT: c_int = 0x2000_0000;
pub const O_SYMLINK: c_int = 0x4000_0000;
pub const O_NOFOLLOW: c_int = 0x8000_0000;
pub const O_ACCMODE: c_int = O_RDONLY | O_WRONLY | O_RDWR;
......@@ -4,6 +4,8 @@
typedef int gid_t;
typedef int uid_t;
typedef int mode_t;
typedef long off_t;
typedef int pid_t;
......
[package]
name = "common"
name = "platform"
version = "0.1.0"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
[dependencies]
syscall = "0.2"
//! fcntl implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/fcntl.h.html
#![no_std]
#![allow(non_camel_case_types)]
#[macro_use]
extern crate syscall;
pub use sys::*;
#[cfg(all(not(feature="no_std"), target_os = "linux"))]
#[path="linux/mod.rs"]
mod sys;
#[cfg(all(not(feature="no_std"), target_os = "redox"))]
#[path="redox/mod.rs"]
mod sys;
pub mod types;
use types::*;
pub fn close(fildes: c_int) -> c_int {
unsafe {
syscall!(CLOSE, fildes) as c_int
}
}
pub fn exit(status: c_int) -> ! {
unsafe {
syscall!(EXIT, status);
}
loop {}
}
pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
unsafe {
syscall!(OPEN, path, oflag, mode) as c_int
}
}
pub fn write(fildes: c_int, buf: &[u8]) -> ssize_t {
unsafe {
syscall!(WRITE, fildes, buf.as_ptr(), buf.len()) as ssize_t
}
}
pub fn exit(status: c_int) -> ! {
syscall::exit(status);
}
pub fn write(fd: c_int, buf: &[u8]) -> ssize_t {
syscall::write(fd, buf);
buf.len() as ssize_t
}
//! fcntl implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/fcntl.h.html
#![no_std]
#![allow(non_camel_case_types)]
// 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.
......
nightly-2018-03-02
#![no_std]
#![feature(lang_items)]
extern crate compiler_builtins;
extern crate platform;
extern crate fcntl;
extern crate unistd;
pub use fcntl::*;
pub use unistd::*;
use core::fmt;
struct PanicWriter;
impl fmt::Write for PanicWriter {
fn write_str(&mut self, s: &str) -> fmt::Result {
platform::write(2, s.as_bytes());
Ok(())
}
}
#[lang = "panic_fmt"]
#[no_mangle]
pub extern "C" fn rust_begin_unwind(fmt: ::core::fmt::Arguments, file: &str, line: u32) -> ! {
loop {}
pub extern "C" fn rust_begin_unwind(fmt: fmt::Arguments, file: &str, line: u32) -> ! {
use fmt::Write;
let _ = PanicWriter.write_fmt(format_args!("{}:{}: {}\n", file, line, fmt));
platform::exit(1);
}
set -ex
cargo build
cargo build --manifest-path crt0/Cargo.toml
cd tests
make clean
make run
/create
/create.out
/write
write: write.c
gcc -nostdinc -nostdlib -I ../include -I ../target/include $< ../target/debug/libc.a -o $@
BINS=\
create \
write
all: $(BINS)
clean:
rm -f write
rm -f $(BINS)
run: $(BINS)
for bin in $(BINS); do echo "\\033[1m$${bin}\\033[0m"; ./$${bin}; done
%: %.c
gcc -nostdinc -nostdlib -I ../include -I ../target/include ../target/debug/libcrt0.a $< ../target/debug/libc.a -o $@
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv) {
int fd = creat("create.out", 0755);
if (fd >= 0) {
write(fd, "Hello World!\n", 14);
close(fd);
return 0;
} else {
write(2, "creat failed\n", 14);
return 1;
}
}
#include <unistd.h>
void _start(void) {
int main(int argc, char **argv) {
write(STDOUT_FILENO, "Hello World!\n", 14);
return 0;
}
......@@ -8,4 +8,4 @@ build = "build.rs"
cbindgen = { path = "../cbindgen" }
[dependencies]
common = { path = "../common" }
platform = { path = "../platform" }
......@@ -2,9 +2,9 @@
#![no_std]
extern crate common;
extern crate platform;
pub use common::*;
pub use platform::types::*;
pub const NULL: c_int = 0;
......@@ -28,7 +28,7 @@ pub const STDERR_FILENO: c_int = 2;
#[no_mangle]
pub extern "C" fn _exit(status: c_int) {
unimplemented!();
platform::exit(status)
}
#[no_mangle]
......@@ -63,7 +63,7 @@ pub extern "C" fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_in
#[no_mangle]
pub extern "C" fn close(fildes: c_int) -> c_int {
unimplemented!();
platform::close(fildes)
}
#[no_mangle]
......@@ -448,7 +448,10 @@ pub extern "C" fn vfork() -> pid_t {
#[no_mangle]
pub extern "C" fn write(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t {
unimplemented!();
use core::slice;
let buf = unsafe { slice::from_raw_parts(buf as *const u8, nbyte as usize) };
platform::write(fildes, buf)
}
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment