mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-10 19:16:51 +00:00
Add support for object::write
This commit is contained in:
parent
5873127ec2
commit
0471ed2776
@ -9,6 +9,9 @@ edition = "2018"
|
||||
[lib]
|
||||
crate-type = ["dylib"]
|
||||
|
||||
[features]
|
||||
backend_object = ["object/write"]
|
||||
|
||||
[dependencies]
|
||||
# These have to be in sync with each other
|
||||
cranelift = { git = "https://github.com/CraneStation/cranelift.git" }
|
||||
@ -29,7 +32,7 @@ libloading = "0.5.1"
|
||||
[dependencies.object]
|
||||
version = "0.14.0"
|
||||
default-features = false
|
||||
features = ["compression", "read", "std", "write"] # We don't need WASM support
|
||||
features = ["compression", "read", "std"] # We don't need WASM support
|
||||
|
||||
# Uncomment to use local checkout of cranelift
|
||||
#[patch."https://github.com/CraneStation/cranelift.git"]
|
||||
|
@ -1,10 +1,13 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use cranelift_module::FuncId;
|
||||
use rustc::session::Session;
|
||||
|
||||
use cranelift_module::{FuncId, Module};
|
||||
|
||||
use faerie::*;
|
||||
use object::{SectionKind, RelocationKind, RelocationEncoding};
|
||||
use object::write::*;
|
||||
use cranelift_faerie::{FaerieBackend, FaerieBuilder, FaerieProduct, FaerieTrapCollection};
|
||||
use cranelift_object::*;
|
||||
|
||||
use gimli::SectionId;
|
||||
@ -73,11 +76,11 @@ pub trait WriteDebugInfo {
|
||||
);
|
||||
}
|
||||
|
||||
impl WriteDebugInfo for Artifact {
|
||||
impl WriteDebugInfo for FaerieProduct {
|
||||
type SectionId = SectionId;
|
||||
|
||||
fn add_debug_section(&mut self, id: SectionId, data: Vec<u8>) -> SectionId {
|
||||
self.declare_with(id.name(), Decl::section(faerie::SectionKind::Debug), data).unwrap();
|
||||
self.artifact.declare_with(id.name(), Decl::section(faerie::SectionKind::Debug), data).unwrap();
|
||||
id
|
||||
}
|
||||
|
||||
@ -89,6 +92,7 @@ impl WriteDebugInfo for Artifact {
|
||||
reloc: &DebugReloc,
|
||||
) {
|
||||
self
|
||||
.artifact
|
||||
.link_with(
|
||||
faerie::Link {
|
||||
from: from.name(),
|
||||
@ -147,3 +151,69 @@ impl WriteDebugInfo for ObjectProduct {
|
||||
}).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Emit {
|
||||
fn emit(self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
impl Emit for FaerieProduct {
|
||||
fn emit(self) -> Vec<u8> {
|
||||
self.artifact.emit().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Emit for ObjectProduct {
|
||||
fn emit(self) -> Vec<u8> {
|
||||
self.object.write().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "backend_object"))]
|
||||
pub fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Artifact)) -> Vec<u8> {
|
||||
let mut metadata_artifact = faerie::Artifact::new(
|
||||
crate::build_isa(sess, true).triple().clone(),
|
||||
name.to_string(),
|
||||
);
|
||||
f(&mut metadata_artifact);
|
||||
metadata_artifact.emit().unwrap()
|
||||
}
|
||||
|
||||
#[cfg(feature = "backend_object")]
|
||||
pub fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object)) -> Vec<u8> {
|
||||
let triple = crate::build_isa(sess, true).triple().clone();
|
||||
let mut metadata_object =
|
||||
object::write::Object::new(triple.binary_format, triple.architecture);
|
||||
metadata_object.add_file_symbol(name.as_bytes().to_vec());
|
||||
f(&mut metadata_object);
|
||||
metadata_object.write().unwrap()
|
||||
}
|
||||
|
||||
pub type Backend = impl cranelift_module::Backend<Product: Emit + WriteDebugInfo>;
|
||||
|
||||
#[cfg(not(feature = "backend_object"))]
|
||||
pub fn make_module(sess: &Session, name: String) -> Module<Backend> {
|
||||
let module: Module<FaerieBackend> = Module::new(
|
||||
FaerieBuilder::new(
|
||||
crate::build_isa(sess, true),
|
||||
name + ".o",
|
||||
FaerieTrapCollection::Disabled,
|
||||
cranelift_module::default_libcall_names(),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
module
|
||||
}
|
||||
|
||||
#[cfg(feature = "backend_object")]
|
||||
pub fn make_module(sess: &Session, name: String) -> Module<Backend> {
|
||||
let module: Module<ObjectBackend> = Module::new(
|
||||
ObjectBuilder::new(
|
||||
crate::build_isa(sess, true),
|
||||
name + ".o",
|
||||
ObjectTrapCollection::Disabled,
|
||||
cranelift_module::default_libcall_names(),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
module
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ use rustc::session::config::{DebugInfo, OutputType};
|
||||
use rustc_codegen_ssa::back::linker::LinkerInfo;
|
||||
use rustc_codegen_ssa::CrateInfo;
|
||||
|
||||
use cranelift_faerie::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::backend::{Emit, WriteDebugInfo};
|
||||
|
||||
pub fn codegen_crate(
|
||||
tcx: TyCtxt<'_>,
|
||||
metadata: EncodedMetadata,
|
||||
@ -147,36 +147,34 @@ fn run_aot(
|
||||
need_metadata_module: bool,
|
||||
) -> Box<CodegenResults> {
|
||||
let new_module = |name: String| {
|
||||
let module: Module<FaerieBackend> = Module::new(
|
||||
FaerieBuilder::new(
|
||||
crate::build_isa(tcx.sess, true),
|
||||
name + ".o",
|
||||
FaerieTrapCollection::Disabled,
|
||||
cranelift_module::default_libcall_names(),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
let module = crate::backend::make_module(tcx.sess, name);
|
||||
assert_eq!(pointer_ty(tcx), module.target_config().pointer_type());
|
||||
module
|
||||
};
|
||||
|
||||
let emit_module = |kind: ModuleKind,
|
||||
mut module: Module<FaerieBackend>,
|
||||
debug: Option<DebugContext>| {
|
||||
fn emit_module<B: Backend>(
|
||||
tcx: TyCtxt<'_>,
|
||||
name: String,
|
||||
kind: ModuleKind,
|
||||
mut module: Module<B>,
|
||||
debug: Option<DebugContext>,
|
||||
) -> CompiledModule
|
||||
where B::Product: Emit + WriteDebugInfo,
|
||||
{
|
||||
module.finalize_definitions();
|
||||
let mut artifact = module.finish().artifact;
|
||||
let mut product = module.finish();
|
||||
|
||||
if let Some(mut debug) = debug {
|
||||
debug.emit(&mut artifact);
|
||||
debug.emit(&mut product);
|
||||
}
|
||||
|
||||
let tmp_file = tcx
|
||||
.output_filenames(LOCAL_CRATE)
|
||||
.temp_path(OutputType::Object, Some(&artifact.name));
|
||||
let obj = artifact.emit().unwrap();
|
||||
.temp_path(OutputType::Object, Some(&name));
|
||||
let obj = product.emit();
|
||||
std::fs::write(&tmp_file, obj).unwrap();
|
||||
CompiledModule {
|
||||
name: artifact.name,
|
||||
name: name,
|
||||
kind,
|
||||
object: Some(tmp_file),
|
||||
bytecode: None,
|
||||
@ -184,7 +182,7 @@ fn run_aot(
|
||||
}
|
||||
};
|
||||
|
||||
let mut faerie_module = new_module("some_file".to_string());
|
||||
let mut module = new_module("some_file".to_string());
|
||||
|
||||
let mut debug = if tcx.sess.opts.debuginfo != DebugInfo::None
|
||||
// macOS debuginfo doesn't work yet (see #303)
|
||||
@ -192,14 +190,14 @@ fn run_aot(
|
||||
{
|
||||
let debug = DebugContext::new(
|
||||
tcx,
|
||||
faerie_module.target_config().pointer_type().bytes() as u8,
|
||||
module.target_config().pointer_type().bytes() as u8,
|
||||
);
|
||||
Some(debug)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
codegen_cgus(tcx, &mut faerie_module, &mut debug);
|
||||
codegen_cgus(tcx, &mut module, &mut debug);
|
||||
|
||||
tcx.sess.abort_if_errors();
|
||||
|
||||
@ -221,17 +219,14 @@ fn run_aot(
|
||||
.as_str()
|
||||
.to_string();
|
||||
|
||||
let mut metadata_artifact = faerie::Artifact::new(
|
||||
crate::build_isa(tcx.sess, true).triple().clone(),
|
||||
metadata_cgu_name.clone(),
|
||||
);
|
||||
crate::metadata::write_metadata(tcx, &mut metadata_artifact);
|
||||
|
||||
let tmp_file = tcx
|
||||
.output_filenames(LOCAL_CRATE)
|
||||
.temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
|
||||
|
||||
let obj = metadata_artifact.emit().unwrap();
|
||||
let obj = crate::backend::with_object(tcx.sess, &metadata_cgu_name, |object| {
|
||||
crate::metadata::write_metadata(tcx, object);
|
||||
});
|
||||
|
||||
std::fs::write(&tmp_file, obj).unwrap();
|
||||
|
||||
(metadata_cgu_name, tmp_file)
|
||||
@ -251,12 +246,16 @@ fn run_aot(
|
||||
Box::new(CodegenResults {
|
||||
crate_name: tcx.crate_name(LOCAL_CRATE),
|
||||
modules: vec![emit_module(
|
||||
tcx,
|
||||
"some_file".to_string(),
|
||||
ModuleKind::Regular,
|
||||
faerie_module,
|
||||
module,
|
||||
debug,
|
||||
)],
|
||||
allocator_module: if created_alloc_shim {
|
||||
Some(emit_module(
|
||||
tcx,
|
||||
"allocator_shim".to_string(),
|
||||
ModuleKind::Allocator,
|
||||
allocator_module,
|
||||
None,
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(rustc_private, never_type, decl_macro)]
|
||||
#![feature(rustc_private, never_type, decl_macro, type_alias_impl_trait, associated_type_bounds)]
|
||||
#![allow(intra_doc_link_resolution_failure)]
|
||||
|
||||
extern crate flate2;
|
||||
|
Loading…
Reference in New Issue
Block a user