Add support for metadata loading

This commit is contained in:
bjorn3 2018-07-24 14:10:53 +02:00
parent eb077f67ac
commit ae44a1a172
6 changed files with 163 additions and 88 deletions

17
Cargo.lock generated
View File

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

View File

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

View File

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

View File

@ -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<T: ?Sized> Copy for *const T {}
#[lang="freeze"]
trait Freeze {}
#[lang="mul"]
trait Mul<RHS = Self> {
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<Rhs: ?Sized = Self> {
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<T: ?Sized> 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<T: ?Sized>(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<T>() -> usize;
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
}
}
use mini_core::*;
fn abc(a: u8) -> u8 {
a * 2

76
mini_core.rs Normal file
View File

@ -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<T: ?Sized> Copy for *const T {}
#[lang="freeze"]
trait Freeze {}
#[lang="mul"]
pub trait Mul<RHS = Self> {
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<Rhs: ?Sized = Self> {
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<T: ?Sized> 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<T: ?Sized>(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<T>() -> usize;
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
}
}

View File

@ -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<owning_ref::ErasedBoxRef<[u8]>, String> {
self.get_dylib_metadata(target, path)
fn get_rlib_metadata(&self, _target: &rustc_target::spec::Target, path: &Path) -> Result<owning_ref::ErasedBoxRef<[u8]>, 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<Vec<u8>, [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<owning_ref::ErasedBoxRef<[u8]>, 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<cranelift_faerie::FaerieBackend>,
product: cranelift_faerie::FaerieProduct,
metadata: Vec<u8>,
crate_name: Symbol,
}
@ -231,7 +268,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
module.finish();
}
let mut translated_module = Module::new(
let mut translated_module: Module<FaerieBackend> = 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::<OngoingCodegen>()
.expect("Expected CraneliftCodegenBackend's OngoingCodegen, found Box<Any>");
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();