diff --git a/Cargo.lock b/Cargo.lock index df75a456740..b20a0c7ec2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,14 @@ dependencies = [ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ar" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "atty" version = "0.2.10" @@ -55,6 +63,11 @@ name = "bitflags" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "byteorder" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "cc" version = "1.0.18" @@ -391,10 +404,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "rustc_codegen_cranelift" version = "0.1.0" dependencies = [ + "ar 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift 0.16.1", "cranelift-faerie 0.16.1", "cranelift-module 0.16.1", "cranelift-simplejit 0.16.1", + "faerie 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -618,11 +633,13 @@ dependencies = [ [metadata] "checksum aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c6d463cbe7ed28720b5b489e7c083eeb8f90d08be2a0d6bb9e1ffea9ce1afa" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum ar 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "095515608290b62ac2427084f9ac3cfeb5dc76067f7d94564db9db1c46cc0a85" "checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1" "checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" "checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" +"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" "checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" "checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" diff --git a/Cargo.toml b/Cargo.toml index 921a65bcedf..dc4f2d93faf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,6 @@ cranelift-module = { path = "./cranelift/lib/module" } cranelift-simplejit = { path = "./cranelift/lib/simplejit" } cranelift-faerie = { path = "./cranelift/lib/faerie" } target-lexicon = "0.0.3" +#goblin = "0.0.17" +faerie = "0.4.4" +ar = "0.6.0" diff --git a/build.sh b/build.sh index a202d300736..85c673d1377 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,5 @@ cargo build || exit 1 -rustc -Zcodegen-backend=$(pwd)/target/debug/librustc_codegen_cranelift.so example.rs --crate-type lib -Og +rustc -Zcodegen-backend=$(pwd)/target/debug/librustc_codegen_cranelift.so mini_core.rs --crate-name mini_core --crate-type lib -Og && +rustc -Zcodegen-backend=$(pwd)/target/debug/librustc_codegen_cranelift.so -L crate=. example.rs --crate-type lib -Og && rustc -Zcodegen-backend=$(pwd)/target/debug/librustc_codegen_cranelift.so ./target/libcore/src/libcore/lib.rs --crate-type lib -Og diff --git a/example.rs b/example.rs index a1dbe0b872e..0df10254f76 100644 --- a/example.rs +++ b/example.rs @@ -1,79 +1,10 @@ -#![feature(no_core, lang_items, intrinsics)] +#![feature(no_core)] #![no_core] #![allow(dead_code)] -#[lang="sized"] -pub trait Sized {} +extern crate mini_core; -#[lang="copy"] -unsafe trait Copy {} - -unsafe impl Copy for u8 {} -unsafe impl Copy for u16 {} -unsafe impl Copy for u32 {} -unsafe impl Copy for u64 {} -unsafe impl Copy for usize {} -unsafe impl Copy for i8 {} -unsafe impl Copy for i16 {} -unsafe impl Copy for i32 {} -unsafe impl Copy for isize {} -unsafe impl<'a, T: ?Sized> Copy for &'a T {} -unsafe impl Copy for *const T {} - -#[lang="freeze"] -trait Freeze {} - -#[lang="mul"] -trait Mul { - type Output; - - #[must_use] - fn mul(self, rhs: RHS) -> Self::Output; -} - -impl Mul for u8 { - type Output = Self; - - fn mul(self, rhs: Self) -> Self { - self * rhs - } -} - -#[lang = "eq"] -pub trait PartialEq { - fn eq(&self, other: &Rhs) -> bool; - fn ne(&self, other: &Rhs) -> bool; -} - -impl PartialEq for u8 { - fn eq(&self, other: &u8) -> bool { (*self) == (*other) } - fn ne(&self, other: &u8) -> bool { (*self) != (*other) } -} - -impl PartialEq for *const T { - fn eq(&self, other: &*const T) -> bool { *self == *other } - fn ne(&self, other: &*const T) -> bool { *self != *other } -} - -#[lang="panic"] -fn panic(_expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! { - loop {} -} - -#[lang = "drop_in_place"] -#[allow(unconditional_recursion)] -unsafe fn drop_in_place(to_drop: *mut T) { - // Code here does not matter - this is replaced by the - // real drop glue by the compiler. - drop_in_place(to_drop); -} - -mod intrinsics { - extern "rust-intrinsic" { - pub fn size_of() -> usize; - pub fn copy(src: *const T, dst: *mut T, count: usize); - } -} +use mini_core::*; fn abc(a: u8) -> u8 { a * 2 diff --git a/mini_core.rs b/mini_core.rs new file mode 100644 index 00000000000..efd0b8818b1 --- /dev/null +++ b/mini_core.rs @@ -0,0 +1,76 @@ +#![feature(no_core, lang_items, intrinsics)] +#![no_core] +#![allow(dead_code)] + +#[lang="sized"] +pub trait Sized {} + +#[lang="copy"] +pub unsafe trait Copy {} + +unsafe impl Copy for u8 {} +unsafe impl Copy for u16 {} +unsafe impl Copy for u32 {} +unsafe impl Copy for u64 {} +unsafe impl Copy for usize {} +unsafe impl Copy for i8 {} +unsafe impl Copy for i16 {} +unsafe impl Copy for i32 {} +unsafe impl Copy for isize {} +unsafe impl<'a, T: ?Sized> Copy for &'a T {} +unsafe impl Copy for *const T {} + +#[lang="freeze"] +trait Freeze {} + +#[lang="mul"] +pub trait Mul { + type Output; + + #[must_use] + fn mul(self, rhs: RHS) -> Self::Output; +} + +impl Mul for u8 { + type Output = Self; + + fn mul(self, rhs: Self) -> Self { + self * rhs + } +} + +#[lang = "eq"] +pub trait PartialEq { + fn eq(&self, other: &Rhs) -> bool; + fn ne(&self, other: &Rhs) -> bool; +} + +impl PartialEq for u8 { + fn eq(&self, other: &u8) -> bool { (*self) == (*other) } + fn ne(&self, other: &u8) -> bool { (*self) != (*other) } +} + +impl PartialEq for *const T { + fn eq(&self, other: &*const T) -> bool { *self == *other } + fn ne(&self, other: &*const T) -> bool { *self != *other } +} + +#[lang="panic"] +pub fn panic(_expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! { + loop {} +} + +#[lang = "drop_in_place"] +#[allow(unconditional_recursion)] +pub unsafe fn drop_in_place(to_drop: *mut T) { + // Code here does not matter - this is replaced by the + // real drop glue by the compiler. + drop_in_place(to_drop); +} + +pub mod intrinsics { + extern "rust-intrinsic" { + pub fn size_of() -> usize; + pub fn copy(src: *const T, dst: *mut T, count: usize); + } +} diff --git a/src/lib.rs b/src/lib.rs index c3294c3c4cf..53abaca552e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,8 +8,12 @@ extern crate rustc_mir; extern crate rustc_codegen_utils; extern crate rustc_target; extern crate rustc_incremental; +#[macro_use] extern crate rustc_data_structures; +extern crate ar; +extern crate faerie; +//extern crate goblin; extern crate target_lexicon; extern crate cranelift; extern crate cranelift_module; @@ -20,7 +24,6 @@ use std::any::Any; use std::sync::{mpsc, Arc}; use std::path::Path; use std::fs::File; -use std::io::Write; use syntax::symbol::Symbol; use rustc::session::{ @@ -35,7 +38,7 @@ use rustc::dep_graph::DepGraph; use rustc::ty::query::Providers; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_codegen_utils::link::{out_filename, build_link_meta}; -use rustc_data_structures::owning_ref; +use rustc_data_structures::owning_ref::{self, OwningRef}; use cranelift::codegen::settings; use cranelift_faerie::*; @@ -91,19 +94,53 @@ pub struct CodegenCx<'a, 'tcx: 'a, B: Backend + 'a> { struct CraneliftMetadataLoader; impl MetadataLoader for CraneliftMetadataLoader { - fn get_rlib_metadata(&self, target: &rustc_target::spec::Target, path: &Path) -> Result, String> { - self.get_dylib_metadata(target, path) + fn get_rlib_metadata(&self, _target: &rustc_target::spec::Target, path: &Path) -> Result, String> { + let mut archive = ar::Archive::new(File::open(path).map_err(|e|format!("{:?}", e))?); + // Iterate over all entries in the archive: + while let Some(entry_result) = archive.next_entry() { + let mut entry = entry_result.map_err(|e|format!("{:?}", e))?; + if entry.header().identifier() == b".rustc.clif_metadata" { + let mut buf = Vec::new(); + ::std::io::copy(&mut entry, &mut buf).map_err(|e|format!("{:?}", e))?; + let buf: OwningRef, [u8]> = OwningRef::new(buf).into(); + return Ok(rustc_erase_owner!(buf.map_owner_box())); + } + } + + Err("couldn't find metadata entry".to_string()) + //self.get_dylib_metadata(target, path) } fn get_dylib_metadata(&self, _target: &rustc_target::spec::Target, _path: &Path) -> Result, String> { - Err("metadata loading is not yet supported".to_string()) + //use goblin::Object; + + //let buffer = ::std::fs::read(path).map_err(|e|format!("{:?}", e))?; + /*match Object::parse(&buffer).map_err(|e|format!("{:?}", e))? { + Object::Elf(elf) => { + println!("elf: {:#?}", &elf); + }, + Object::PE(pe) => { + println!("pe: {:#?}", &pe); + }, + Object::Mach(mach) => { + println!("mach: {:#?}", &mach); + }, + Object::Archive(archive) => { + return Err(format!("archive: {:#?}", &archive)); + }, + Object::Unknown(magic) => { + return Err(format!("unknown magic: {:#x}", magic)) + } + }*/ + Err("dylib metadata loading is not yet supported".to_string()) } } struct CraneliftCodegenBackend; struct OngoingCodegen { - translated_module: Module, + product: cranelift_faerie::FaerieProduct, + metadata: Vec, crate_name: Symbol, } @@ -231,7 +268,7 @@ impl CodegenBackend for CraneliftCodegenBackend { module.finish(); } - let mut translated_module = Module::new( + let mut translated_module: Module = Module::new( FaerieBuilder::new( isa, "some_file.o".to_string(), @@ -241,13 +278,9 @@ impl CodegenBackend for CraneliftCodegenBackend { .unwrap() ); - let metadata_id = translated_module.declare_data(".rustc.metadata", Linkage::Export, false).unwrap(); - let mut data_ctx = DataContext::new(); - data_ctx.define(metadata.raw_data.clone().into_boxed_slice(), Writability::Readonly); - translated_module.define_data(metadata_id, &data_ctx).unwrap(); - Box::new(::OngoingCodegen { - translated_module, + product: translated_module.finish(), + metadata: metadata.raw_data, crate_name: tcx.crate_name(LOCAL_CRATE), }) } @@ -261,7 +294,19 @@ impl CodegenBackend for CraneliftCodegenBackend { ) -> Result<(), CompileIncomplete> { let ongoing_codegen = *ongoing_codegen.downcast::() .expect("Expected CraneliftCodegenBackend's OngoingCodegen, found Box"); - let artifact = ongoing_codegen.translated_module.finish().artifact; + + let mut artifact = ongoing_codegen.product.artifact; + let metadata = ongoing_codegen.metadata; + + artifact.declare_with( + ".rustc.clif_metadata", + faerie::artifact::Decl::Data { + global: true, + writeable: false + }, + metadata.clone(), + ).unwrap(); + for &crate_type in sess.opts.crate_types.iter() { if crate_type != CrateType::CrateTypeRlib /*&& crate_type != CrateType::CrateTypeDylib*/ { sess.fatal(&format!("Unsupported crate type: {:?}", crate_type)); @@ -269,7 +314,9 @@ impl CodegenBackend for CraneliftCodegenBackend { let output_name = out_filename(sess, crate_type, &outputs, &ongoing_codegen.crate_name.as_str()); let file = File::create(&output_name).unwrap(); - artifact.write(file).unwrap(); + let mut builder = ar::Builder::new(file); + builder.append(&ar::Header::new(b".rustc.clif_metadata".to_vec(), metadata.len() as u64), ::std::io::Cursor::new(metadata.clone())).unwrap(); + //artifact.write(file).unwrap(); } sess.abort_if_errors();