diff options
| author | bors <bors@rust-lang.org> | 2021-05-14 12:58:58 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-05-14 12:58:58 +0000 |
| commit | 75da570d784a798a34ff1e5048cd9a6a2fb23170 (patch) | |
| tree | 7e2ffecffbd250a725092db3d0bc5190c52b4fdb /compiler/rustc_codegen_cranelift/src | |
| parent | 36a4d14c7edba21bba14df00b9e6e4a111dfc6f2 (diff) | |
| parent | 6381aaf8ae2df01cdb70b6f3123153cf4f1e03cd (diff) | |
| download | rust-75da570d784a798a34ff1e5048cd9a6a2fb23170.tar.gz rust-75da570d784a798a34ff1e5048cd9a6a2fb23170.zip | |
Auto merge of #83640 - bjorn3:shared_metadata_reader, r=nagisa
Use the object crate for metadata reading This allows sharing the metadata reader between cg_llvm, cg_clif and other codegen backends. This is not currently useful for rlib reading with cg_spirv ([rust-gpu](https://github.com/EmbarkStudios/rust-gpu/)) as it uses tar rather than ar as .rlib format, but it is useful for dylib reading required for loading proc macros. (cc `@eddyb)` The object crate is already trusted as dependency of libstd through backtrace. As far as I know it supports reading all object file formats used by targets for which we support rust dylibs with crate metadata, but I am not certain. If this happens to not be the case, I could keep using LLVM for reading dylib metadata. Marked as WIP for a perf run and as it is based on #83637.
Diffstat (limited to 'compiler/rustc_codegen_cranelift/src')
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/metadata.rs | 66 |
2 files changed, 2 insertions, 66 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 4271f695f91..ff6e1856059 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -165,7 +165,7 @@ impl CodegenBackend for CraneliftCodegenBackend { } fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> { - Box::new(crate::metadata::CraneliftMetadataLoader) + Box::new(rustc_codegen_ssa::back::metadata::DefaultMetadataLoader) } fn provide(&self, _providers: &mut Providers) {} diff --git a/compiler/rustc_codegen_cranelift/src/metadata.rs b/compiler/rustc_codegen_cranelift/src/metadata.rs index 882232fde09..ab238244d68 100644 --- a/compiler/rustc_codegen_cranelift/src/metadata.rs +++ b/compiler/rustc_codegen_cranelift/src/metadata.rs @@ -1,73 +1,9 @@ -//! Reading and writing of the rustc metadata for rlibs and dylibs +//! Writing of the rustc metadata for dylibs -use std::fs::File; -use std::path::Path; - -use rustc_codegen_ssa::METADATA_FILENAME; -use rustc_data_structures::memmap::Mmap; -use rustc_data_structures::owning_ref::OwningRef; -use rustc_data_structures::rustc_erase_owner; -use rustc_data_structures::sync::MetadataRef; -use rustc_middle::middle::cstore::MetadataLoader; use rustc_middle::ty::TyCtxt; -use rustc_target::spec::Target; use crate::backend::WriteMetadata; -/// The metadata loader used by cg_clif. -/// -/// The metadata is stored in the same format as cg_llvm. -/// -/// # Metadata location -/// -/// <dl> -/// <dt>rlib</dt> -/// <dd>The metadata can be found in the `lib.rmeta` file inside of the ar archive.</dd> -/// <dt>dylib</dt> -/// <dd>The metadata can be found in the `.rustc` section of the shared library.</dd> -/// </dl> -pub(crate) struct CraneliftMetadataLoader; - -fn load_metadata_with( - path: &Path, - f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>, -) -> Result<MetadataRef, String> { - let file = File::open(path).map_err(|e| format!("{:?}", e))?; - let data = unsafe { Mmap::map(file) }.map_err(|e| format!("{:?}", e))?; - let metadata = OwningRef::new(data).try_map(f)?; - return Ok(rustc_erase_owner!(metadata.map_owner_box())); -} - -impl MetadataLoader for CraneliftMetadataLoader { - fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> { - load_metadata_with(path, |data| { - let archive = object::read::archive::ArchiveFile::parse(&*data) - .map_err(|e| format!("{:?}", e))?; - - for entry_result in archive.members() { - let entry = entry_result.map_err(|e| format!("{:?}", e))?; - if entry.name() == METADATA_FILENAME.as_bytes() { - return Ok(entry.data()); - } - } - - Err("couldn't find metadata entry".to_string()) - }) - } - - fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> { - use object::{Object, ObjectSection}; - - load_metadata_with(path, |data| { - let file = object::File::parse(&data).map_err(|e| format!("parse: {:?}", e))?; - file.section_by_name(".rustc") - .ok_or("no .rustc section")? - .data() - .map_err(|e| format!("failed to read .rustc section: {:?}", e)) - }) - } -} - // Adapted from https://github.com/rust-lang/rust/blob/da573206f87b5510de4b0ee1a9c044127e409bd3/src/librustc_codegen_llvm/base.rs#L47-L112 pub(crate) fn write_metadata<O: WriteMetadata>(tcx: TyCtxt<'_>, object: &mut O) { use snap::write::FrameEncoder; |
