diff --git a/mk/platform.mk b/mk/platform.mk index c2fe8e98e453a..2956c6cd251e6 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -343,6 +343,7 @@ CFG_PATH_MUNGE_mips-unknown-linux-gnu := true CFG_LDPATH_mips-unknown-linux-gnu := CFG_RUN_mips-unknown-linux-gnu= CFG_RUN_TARG_mips-unknown-linux-gnu= +RUSTC_FLAGS_mips-unknown-linux-gnu := --linker=$(CXX_mips-unknown-linux-gnu) --target-cpu mips32r2 --target-feature +mips32r2,+o32 # i686-pc-mingw32 configuration CC_i686-pc-mingw32=$(CC) @@ -480,7 +481,7 @@ define CFG_MAKE_TOOLCHAIN $$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \ $$(call CFG_INSTALL_NAME_$(1),$$(4)) - ifneq ($(HOST_$(1)),arm) + ifeq ($$(findstring $(HOST_$(1)),arm mips),) # We're using llvm-mc as our assembler because it supports # .cfi pseudo-ops on mac @@ -492,7 +493,7 @@ define CFG_MAKE_TOOLCHAIN -o=$$(1) else - # For the ARM crosses, use the toolchain assembler + # For the ARM and MIPS crosses, use the toolchain assembler # XXX: We should be able to use the LLVM assembler CFG_ASSEMBLE_$(1)=$$(CC_$(1)) $$(CFG_DEPEND_FLAGS) $$(2) -c -o $$(1) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 4c679798bce54..762c658ea6ebf 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2442,11 +2442,6 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, unsafe { llvm::LLVMPositionBuilderAtEnd(bld, llbb); - let crate_map = ccx.crate_map; - let opaque_crate_map = do "crate_map".with_c_str |buf| { - llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf) - }; - let (start_fn, args) = if use_start_lang_item { let start_def_id = match ccx.tcx.lang_items.require(StartFnLangItem) { Ok(id) => id, @@ -2469,8 +2464,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, C_null(Type::opaque_box(ccx).ptr_to()), opaque_rust_main, llvm::LLVMGetParam(llfn, 0), - llvm::LLVMGetParam(llfn, 1), - opaque_crate_map + llvm::LLVMGetParam(llfn, 1) ] }; (start_fn, args) @@ -2479,8 +2473,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, let args = ~[ C_null(Type::opaque_box(ccx).ptr_to()), llvm::LLVMGetParam(llfn, 0 as c_uint), - llvm::LLVMGetParam(llfn, 1 as c_uint), - opaque_crate_map + llvm::LLVMGetParam(llfn, 1 as c_uint) ]; (rust_main, args) @@ -2661,13 +2654,16 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef { } ast::foreign_item_static(*) => { let ident = foreign::link_name(ccx, ni); - let g = do ident.with_c_str |buf| { - unsafe { + unsafe { + let g = do ident.with_c_str |buf| { let ty = type_of(ccx, ty); llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf) + }; + if attr::contains_name(ni.attrs, "weak_linkage") { + lib::llvm::SetLinkage(g, lib::llvm::ExternalWeakLinkage); } - }; - g + g + } } } } diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 8d7dbdf263ed8..45a65f954a3a9 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -402,8 +402,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt, bound_lifetime_names: opt_vec::Empty, inputs: ~[ ty::mk_int(), - ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8())), - ty::mk_imm_ptr(tcx, ty::mk_u8()) + ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8())) ], output: ty::mk_int() } diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 790dc886c0497..a5a2def450e8a 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -294,7 +294,6 @@ pub mod types { pub type ssize_t = i32; } #[cfg(target_arch = "x86")] - #[cfg(target_arch = "mips")] pub mod posix01 { use libc::types::os::arch::c95::{c_short, c_long, time_t}; use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t}; @@ -305,7 +304,6 @@ pub mod types { pub type blksize_t = i32; pub type blkcnt_t = i32; - #[cfg(target_arch = "x86")] pub struct stat { st_dev: dev_t, __pad1: c_short, @@ -328,30 +326,6 @@ pub mod types { __unused4: c_long, __unused5: c_long, } - - #[cfg(target_arch = "mips")] - pub struct stat { - st_dev: c_ulong, - st_pad1: [c_long, ..3], - st_ino: ino_t, - st_mode: mode_t, - st_nlink: nlink_t, - st_uid: uid_t, - st_gid: gid_t, - st_rdev: c_ulong, - st_pad2: [c_long, ..2], - st_size: off_t, - st_pad3: c_long, - st_atime: time_t, - st_atime_nsec: c_long, - st_mtime: time_t, - st_mtime_nsec: c_long, - st_ctime: time_t, - st_ctime_nsec: c_long, - st_blksize: blksize_t, - st_blocks: blkcnt_t, - st_pad5: [c_long, ..14], - } } #[cfg(target_arch = "arm")] pub mod posix01 { @@ -385,6 +359,40 @@ pub mod types { st_ino: c_ulonglong } } + #[cfg(target_arch = "mips")] + pub mod posix01 { + use libc::types::os::arch::c95::{c_long, c_ulong, time_t}; + use libc::types::os::arch::posix88::{gid_t, ino_t}; + use libc::types::os::arch::posix88::{mode_t, off_t}; + use libc::types::os::arch::posix88::{uid_t}; + + pub type nlink_t = u32; + pub type blksize_t = i32; + pub type blkcnt_t = i32; + + pub struct stat { + st_dev: c_ulong, + st_pad1: [c_long, ..3], + st_ino: ino_t, + st_mode: mode_t, + st_nlink: nlink_t, + st_uid: uid_t, + st_gid: gid_t, + st_rdev: c_ulong, + st_pad2: [c_long, ..2], + st_size: off_t, + st_pad3: c_long, + st_atime: time_t, + st_atime_nsec: c_long, + st_mtime: time_t, + st_mtime_nsec: c_long, + st_ctime: time_t, + st_ctime_nsec: c_long, + st_blksize: blksize_t, + st_blocks: blkcnt_t, + st_pad5: [c_long, ..14], + } + } pub mod posix08 {} pub mod bsd44 {} pub mod extra {} @@ -1633,6 +1641,111 @@ pub mod consts { pub static EPIPE : c_int = 32; pub static EDOM : c_int = 33; pub static ERANGE : c_int = 34; + + pub static ENOMSG: c_int = 35; + pub static EIDRM: c_int = 36; + pub static ECHRNG: c_int = 37; + pub static EL2NSYNC: c_int = 38; + pub static EL3HLT: c_int = 39; + pub static EL3RST: c_int = 40; + pub static ELNRNG: c_int = 41; + pub static EUNATCH: c_int = 42; + pub static ENOCSI: c_int = 43; + pub static EL2HLT: c_int = 44; + pub static EDEADLK: c_int = 45; + pub static ENOLCK: c_int = 46; + pub static EBADE: c_int = 50; + pub static EBADR: c_int = 51; + pub static EXFULL: c_int = 52; + pub static ENOANO: c_int = 53; + pub static EBADRQC: c_int = 54; + pub static EBADSLT: c_int = 55; + pub static EDEADLOCK: c_int = 56; + pub static EBFONT: c_int = 59; + pub static ENOSTR: c_int = 60; + pub static ENODATA: c_int = 61; + pub static ETIME: c_int = 62; + pub static ENOSR: c_int = 63; + pub static ENONET: c_int = 64; + pub static ENOPKG: c_int = 65; + pub static EREMOTE: c_int = 66; + pub static ENOLINK: c_int = 67; + pub static EADV: c_int = 68; + pub static ESRMNT: c_int = 69; + pub static ECOMM: c_int = 70; + pub static EPROTO: c_int = 71; + pub static EDOTDOT: c_int = 73; + pub static EMULTIHOP: c_int = 74; + pub static EBADMSG: c_int = 77; + pub static ENAMETOOLONG: c_int = 78; + pub static EOVERFLOW: c_int = 79; + pub static ENOTUNIQ: c_int = 80; + pub static EBADFD: c_int = 81; + pub static EREMCHG: c_int = 82; + pub static ELIBACC: c_int = 83; + pub static ELIBBAD: c_int = 84; + pub static ELIBSCN: c_int = 95; + pub static ELIBMAX: c_int = 86; + pub static ELIBEXEC: c_int = 87; + pub static EILSEQ: c_int = 88; + pub static ENOSYS: c_int = 89; + pub static ELOOP: c_int = 90; + pub static ERESTART: c_int = 91; + pub static ESTRPIPE: c_int = 92; + pub static ENOTEMPTY: c_int = 93; + pub static EUSERS: c_int = 94; + pub static ENOTSOCK: c_int = 95; + pub static EDESTADDRREQ: c_int = 96; + pub static EMSGSIZE: c_int = 97; + pub static EPROTOTYPE: c_int = 98; + pub static ENOPROTOOPT: c_int = 99; + pub static EPROTONOSUPPORT: c_int = 120; + pub static ESOCKTNOSUPPORT: c_int = 121; + pub static EOPNOTSUPP: c_int = 122; + pub static EPFNOSUPPORT: c_int = 123; + pub static EAFNOSUPPORT: c_int = 124; + pub static EADDRINUSE: c_int = 125; + pub static EADDRNOTAVAIL: c_int = 126; + pub static ENETDOWN: c_int = 127; + pub static ENETUNREACH: c_int = 128; + pub static ENETRESET: c_int = 129; + pub static ECONNABORTED: c_int = 130; + pub static ECONNRESET: c_int = 131; + pub static ENOBUFS: c_int = 132; + pub static EISCONN: c_int = 133; + pub static ENOTCONN: c_int = 134; + pub static EUCLEAN: c_int = 135; + pub static ENOTNAM: c_int = 137; + pub static ENAVAIL: c_int = 138; + pub static EISNAM: c_int = 139; + pub static EREMOTEIO: c_int = 140; + pub static ESHUTDOWN: c_int = 143; + pub static ETOOMANYREFS: c_int = 144; + pub static ETIMEDOUT: c_int = 145; + pub static ECONNREFUSED: c_int = 146; + pub static EHOSTDOWN: c_int = 147; + pub static EHOSTUNREACH: c_int = 148; + pub static EWOULDBLOCK: c_int = EAGAIN; + pub static EALREADY: c_int = 149; + pub static EINPROGRESS: c_int = 150; + pub static ESTALE: c_int = 151; + pub static ECANCELED: c_int = 158; + + pub static ENOMEDIUM: c_int = 159; + pub static EMEDIUMTYPE: c_int = 160; + pub static ENOKEY: c_int = 161; + pub static EKEYEXPIRED: c_int = 162; + pub static EKEYREVOKED: c_int = 163; + pub static EKEYREJECTED: c_int = 164; + + pub static EOWNERDEAD: c_int = 165; + pub static ENOTRECOVERABLE: c_int = 166; + + pub static ERFKILL: c_int = 167; + + pub static EHWPOISON: c_int = 168; + + pub static EDQUOT: c_int = 1133; } pub mod posix01 { use libc::types::os::arch::c95::c_int; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index e58acf70ca460..1dc1d1d677648 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1647,7 +1647,7 @@ pub mod consts { pub use os::consts::arm::*; #[cfg(target_arch = "mips")] - use os::consts::mips::*; + pub use os::consts::mips::*; pub mod unix { pub static FAMILY: &'static str = "unix"; diff --git a/src/libstd/rt/crate_map.rs b/src/libstd/rt/crate_map.rs index 270b5e5b1372e..f6ebb8bcdfff7 100644 --- a/src/libstd/rt/crate_map.rs +++ b/src/libstd/rt/crate_map.rs @@ -16,7 +16,14 @@ use vec; use hashmap::HashSet; use container::MutableSet; -pub struct ModEntry{ +extern { + #[cfg(not(stage0))] + #[weak_linkage] + #[link_name = "_rust_crate_map_toplevel"] + static CRATE_MAP: CrateMap; +} + +pub struct ModEntry { name: *c_char, log_level: *mut u32 } @@ -34,6 +41,11 @@ struct CrateMap { children: [*CrateMap, ..1] } +#[cfg(not(stage0))] +pub fn get_crate_map() -> *CrateMap { + &'static CRATE_MAP as *CrateMap +} + unsafe fn version(crate_map: *CrateMap) -> i32 { match (*crate_map).version { 1 => return 1, diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs index fbe05267cf4f9..26072079bcc18 100644 --- a/src/libstd/rt/logging.rs +++ b/src/libstd/rt/logging.rs @@ -12,6 +12,7 @@ use libc::{uintptr_t, exit, STDERR_FILENO}; use option::{Some, None, Option}; use rt::util::dumb_println; use rt::crate_map::{ModEntry, iter_crate_map}; +#[cfg(not(stage0))] use rt::crate_map::get_crate_map; use str::StrSlice; use str::raw::from_c_str; use u32; @@ -211,6 +212,7 @@ impl Logger for StdErrLogger { /// Configure logging by traversing the crate map and setting the /// per-module global logging flags based on the logging spec #[fixed_stack_segment] #[inline(never)] +#[cfg(stage0)] pub fn init(crate_map: *u8) { use os; @@ -224,6 +226,22 @@ pub fn init(crate_map: *u8) { } } } +#[cfg(not(stage0))] +pub fn init() { + use os; + + let crate_map = get_crate_map() as *u8; + + let log_spec = os::getenv("RUST_LOG"); + match log_spec { + Some(spec) => { + update_log_settings(crate_map, spec); + } + None => { + update_log_settings(crate_map, ~""); + } + } +} #[fixed_stack_segment] #[inline(never)] pub fn console_on() { unsafe { rust_log_console_on() } } diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 6df857b8d5517..1ad258c3edf6c 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -171,11 +171,11 @@ pub mod borrowck; /// /// * `argc` & `argv` - The argument vector. On Unix this information is used /// by os::args. -/// * `crate_map` - Runtime information about the executing crate, mostly for logging /// /// # Return value /// /// The return value is used as the process return code. 0 on success, 101 on error. +#[cfg(stage0)] pub fn start(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int { init(argc, argv, crate_map); @@ -184,12 +184,22 @@ pub fn start(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int { return exit_code; } +#[cfg(not(stage0))] +pub fn start(argc: int, argv: **u8, main: ~fn()) -> int { + + init(argc, argv); + let exit_code = run(main); + cleanup(); + + return exit_code; +} /// Like `start` but creates an additional scheduler on the current thread, /// which in most cases will be the 'main' thread, and pins the main task to it. /// /// This is appropriate for running code that must execute on the main thread, /// such as the platform event loop and GUI. +#[cfg(stage0)] pub fn start_on_main_thread(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int { init(argc, argv, crate_map); let exit_code = run_on_main_thread(main); @@ -197,12 +207,21 @@ pub fn start_on_main_thread(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) return exit_code; } +#[cfg(not(stage0))] +pub fn start_on_main_thread(argc: int, argv: **u8, main: ~fn()) -> int { + init(argc, argv); + let exit_code = run_on_main_thread(main); + cleanup(); + + return exit_code; +} /// One-time runtime initialization. /// /// Initializes global state, including frobbing /// the crate's logging flags, registering GC /// metadata, and storing the process arguments. +#[cfg(stage0)] pub fn init(argc: int, argv: **u8, crate_map: *u8) { // XXX: Derefing these pointers is not safe. // Need to propagate the unsafety to `start`. @@ -212,6 +231,16 @@ pub fn init(argc: int, argv: **u8, crate_map: *u8) { logging::init(crate_map); } } +#[cfg(not(stage0))] +pub fn init(argc: int, argv: **u8) { + // XXX: Derefing these pointers is not safe. + // Need to propagate the unsafety to `start`. + unsafe { + args::init(argc, argv); + env::init(); + logging::init(); + } +} /// One-time runtime cleanup. pub fn cleanup() { diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index 1d839b55195be..baa705514894b 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -93,6 +93,7 @@ pub unsafe fn check_not_borrowed(a: *u8, borrowck::check_not_borrowed(a, file, line) } +#[cfg(stage0)] #[lang="start"] pub fn start(main: *u8, argc: int, argv: **c_char, crate_map: *u8) -> int { @@ -105,3 +106,16 @@ pub fn start(main: *u8, argc: int, argv: **c_char, }; } } + +#[cfg(not(stage0))] +#[lang="start"] +pub fn start(main: *u8, argc: int, argv: **c_char) -> int { + use rt; + + unsafe { + return do rt::start(argc, argv as **u8) { + let main: extern "Rust" fn() = transmute(main); + main(); + }; + } +}