diff --git a/Cargo.lock b/Cargo.lock index dab1e3f3860..d67181bd562 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,6 +155,17 @@ dependencies = [ "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cranelift-object" +version = "0.46.1" +source = "git+https://github.com/CraneStation/cranelift.git#387593d6c94d291e614c08d7a03f77b40efa451d" +dependencies = [ + "cranelift-codegen 0.46.1 (git+https://github.com/CraneStation/cranelift.git)", + "cranelift-module 0.46.1 (git+https://github.com/CraneStation/cranelift.git)", + "object 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cranelift-simplejit" version = "0.46.1" @@ -332,8 +343,10 @@ name = "object" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "goblin 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "scroll 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -411,6 +424,7 @@ dependencies = [ "cranelift 0.46.1 (git+https://github.com/CraneStation/cranelift.git)", "cranelift-faerie 0.46.1 (git+https://github.com/CraneStation/cranelift.git)", "cranelift-module 0.46.1 (git+https://github.com/CraneStation/cranelift.git)", + "cranelift-object 0.46.1 (git+https://github.com/CraneStation/cranelift.git)", "cranelift-simplejit 0.46.1 (git+https://github.com/CraneStation/cranelift.git)", "faerie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "gimli 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -594,6 +608,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cranelift-frontend 0.46.1 (git+https://github.com/CraneStation/cranelift.git)" = "" "checksum cranelift-module 0.46.1 (git+https://github.com/CraneStation/cranelift.git)" = "" "checksum cranelift-native 0.46.1 (git+https://github.com/CraneStation/cranelift.git)" = "" +"checksum cranelift-object 0.46.1 (git+https://github.com/CraneStation/cranelift.git)" = "" "checksum cranelift-simplejit 0.46.1 (git+https://github.com/CraneStation/cranelift.git)" = "" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" diff --git a/Cargo.toml b/Cargo.toml index 66256cd68e1..f3b9e843788 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ crate-type = ["dylib"] cranelift = { git = "https://github.com/CraneStation/cranelift.git" } cranelift-module = { git = "https://github.com/CraneStation/cranelift.git" } cranelift-faerie = { git = "https://github.com/CraneStation/cranelift.git" } +cranelift-object = { git = "https://github.com/CraneStation/cranelift.git" } target-lexicon = "0.8.1" faerie = "0.11.0" @@ -28,7 +29,7 @@ libloading = "0.5.1" [dependencies.object] version = "0.14.0" default-features = false -features = ["compression", "read", "std"] # We don't need WASM support +features = ["compression", "read", "std", "write"] # We don't need WASM support # Uncomment to use local checkout of cranelift #[patch."https://github.com/CraneStation/cranelift.git"] @@ -36,6 +37,7 @@ features = ["compression", "read", "std"] # We don't need WASM support #cranelift-module = { path = "../cranelift/cranelift-module" } #cranelift-simplejit = { path = "../cranelift/cranelift-simplejit" } #cranelift-faerie = { path = "../cranelift/cranelift-faerie" } +#cranelift-object = { path = "../cranelift/cranelift-object" } #[patch.crates-io] #gimli = { path = "../" } diff --git a/src/backend.rs b/src/backend.rs new file mode 100644 index 00000000000..f070e95f535 --- /dev/null +++ b/src/backend.rs @@ -0,0 +1,48 @@ +pub trait Product { + fn add_rustc_section(&mut self, symbol_name: String, data: Vec, is_like_osx: bool); +} + +impl Product for faerie::Artifact { + fn add_rustc_section(&mut self, symbol_name: String, data: Vec, is_like_osx: bool) { + self + .declare(".rustc", faerie::Decl::section(faerie::SectionKind::Data)) + .unwrap(); + self + .define_with_symbols(".rustc", data, { + let mut map = std::collections::BTreeMap::new(); + // FIXME implement faerie elf backend section custom symbols + // For MachO this is necessary to prevent the linker from throwing away the .rustc section, + // but for ELF it isn't. + if is_like_osx { + map.insert( + symbol_name, + 0, + ); + } + map + }) + .unwrap(); + } +} + +impl Product for object::write::Object { + fn add_rustc_section(&mut self, symbol_name: String, data: Vec, is_like_osx: bool) { + let segment = self.segment_name(object::write::StandardSegment::Data).to_vec(); + let section_id = self.add_section(segment, b".rustc".to_vec(), object::SectionKind::Data); + let offset = self.append_section_data(section_id, &data, 1); + // FIXME implement faerie elf backend section custom symbols + // For MachO this is necessary to prevent the linker from throwing away the .rustc section, + // but for ELF it isn't. + if is_like_osx { + self.add_symbol(object::write::Symbol { + name: symbol_name.into_bytes(), + value: offset, + size: data.len() as u64, + kind: object::SymbolKind::Data, + scope: object::SymbolScope::Compilation, + weak: false, + section: Some(section_id), + }); + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 866a3d31146..7e68f10ede0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,6 +35,7 @@ mod allocator; mod analyze; mod archive; mod base; +mod backend; mod cast; mod codegen_i128; mod common; diff --git a/src/metadata.rs b/src/metadata.rs index 8d17922725a..76c86e73853 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -9,6 +9,8 @@ use rustc_data_structures::owning_ref::{self, OwningRef}; use rustc_data_structures::rustc_erase_owner; use rustc_target::spec::Target; +use crate::backend::Product; + pub struct CraneliftMetadataLoader; impl MetadataLoader for CraneliftMetadataLoader { @@ -51,7 +53,7 @@ impl MetadataLoader for CraneliftMetadataLoader { } // Adapted from https://github.com/rust-lang/rust/blob/da573206f87b5510de4b0ee1a9c044127e409bd3/src/librustc_codegen_llvm/base.rs#L47-L112 -pub fn write_metadata(tcx: TyCtxt<'_>, artifact: &mut faerie::Artifact) -> EncodedMetadata { +pub fn write_metadata(tcx: TyCtxt<'_>, product: &mut P) -> EncodedMetadata { use flate2::write::DeflateEncoder; use flate2::Compression; use std::io::Write; @@ -95,24 +97,11 @@ pub fn write_metadata(tcx: TyCtxt<'_>, artifact: &mut faerie::Artifact) -> Encod .write_all(&metadata.raw_data) .unwrap(); - artifact - .declare(".rustc", faerie::Decl::section(faerie::SectionKind::Data)) - .unwrap(); - artifact - .define_with_symbols(".rustc", compressed, { - let mut map = std::collections::BTreeMap::new(); - // FIXME implement faerie elf backend section custom symbols - // For MachO this is necessary to prevent the linker from throwing away the .rustc section, - // but for ELF it isn't. - if tcx.sess.target.target.options.is_like_osx { - map.insert( - rustc::middle::exported_symbols::metadata_symbol_name(tcx), - 0, - ); - } - map - }) - .unwrap(); + product.add_rustc_section( + rustc::middle::exported_symbols::metadata_symbol_name(tcx), + compressed, + tcx.sess.target.target.options.is_like_osx, + ); metadata }