From 267d55d44acf6bb2821de39d4f868650ff0a9c7b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 29 Mar 2021 11:39:13 +0200 Subject: [PATCH 1/8] Use the object crate for metadata reading --- Cargo.lock | 9 ++ compiler/rustc_codegen_cranelift/src/lib.rs | 2 +- .../rustc_codegen_cranelift/src/metadata.rs | 66 +------------- compiler/rustc_codegen_llvm/src/lib.rs | 2 +- compiler/rustc_codegen_llvm/src/metadata.rs | 89 ------------------- compiler/rustc_codegen_ssa/Cargo.toml | 1 + .../rustc_codegen_ssa/src/back/metadata.rs | 65 ++++++++++++++ compiler/rustc_codegen_ssa/src/back/mod.rs | 1 + 8 files changed, 79 insertions(+), 156 deletions(-) create mode 100644 compiler/rustc_codegen_ssa/src/back/metadata.rs diff --git a/Cargo.lock b/Cargo.lock index 77b917448e950..dc688e3a513cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2348,8 +2348,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" dependencies = [ "compiler_builtins", + "flate2", "rustc-std-workspace-alloc", "rustc-std-workspace-core", + "wasmparser", ] [[package]] @@ -3700,6 +3702,7 @@ dependencies = [ "itertools 0.9.0", "jobserver", "libc", + "object", "pathdiff", "rustc_apfloat", "rustc_ast", @@ -5618,6 +5621,12 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "wasmparser" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32fddd575d477c6e9702484139cf9f23dcd554b06d185ed0f56c857dd3a47aa6" + [[package]] name = "winapi" version = "0.2.8" diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 32f403957025a..1ade7c77d123a 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 { - 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 882232fde09d2..ab238244d68d5 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 -/// -///
-///
rlib
-///
The metadata can be found in the `lib.rmeta` file inside of the ar archive.
-///
dylib
-///
The metadata can be found in the `.rustc` section of the shared library.
-///
-pub(crate) struct CraneliftMetadataLoader; - -fn load_metadata_with( - path: &Path, - f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>, -) -> Result { - 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 { - 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 { - 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(tcx: TyCtxt<'_>, object: &mut O) { use snap::write::FrameEncoder; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 5ca4b226c38fb..8f95afc1b9181 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -250,7 +250,7 @@ impl CodegenBackend for LlvmCodegenBackend { } fn metadata_loader(&self) -> Box { - Box::new(metadata::LlvmMetadataLoader) + Box::new(rustc_codegen_ssa::back::metadata::DefaultMetadataLoader) } fn provide(&self, providers: &mut ty::query::Providers) { diff --git a/compiler/rustc_codegen_llvm/src/metadata.rs b/compiler/rustc_codegen_llvm/src/metadata.rs index decc1e1f70007..4bad93a75674b 100644 --- a/compiler/rustc_codegen_llvm/src/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/metadata.rs @@ -1,94 +1,9 @@ -use crate::llvm; -use crate::llvm::archive_ro::ArchiveRO; -use crate::llvm::{mk_section_iter, False, ObjectFile}; -use rustc_middle::middle::cstore::MetadataLoader; use rustc_target::spec::Target; -use rustc_codegen_ssa::METADATA_FILENAME; -use rustc_data_structures::owning_ref::OwningRef; -use rustc_data_structures::rustc_erase_owner; -use tracing::debug; - use rustc_fs_util::path_to_c_string; use std::path::Path; use std::slice; -pub use rustc_data_structures::sync::MetadataRef; - -pub struct LlvmMetadataLoader; - -impl MetadataLoader for LlvmMetadataLoader { - fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result { - // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap - // internally to read the file. We also avoid even using a memcpy by - // just keeping the archive along while the metadata is in use. - let archive = - ArchiveRO::open(filename).map(|ar| OwningRef::new(Box::new(ar))).map_err(|e| { - debug!("llvm didn't like `{}`: {}", filename.display(), e); - format!("failed to read rlib metadata in '{}': {}", filename.display(), e) - })?; - let buf: OwningRef<_, [u8]> = archive.try_map(|ar| { - ar.iter() - .filter_map(|s| s.ok()) - .find(|sect| sect.name() == Some(METADATA_FILENAME)) - .map(|s| s.data()) - .ok_or_else(|| { - debug!("didn't find '{}' in the archive", METADATA_FILENAME); - format!("failed to read rlib metadata: '{}'", filename.display()) - }) - })?; - Ok(rustc_erase_owner!(buf)) - } - - fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result { - unsafe { - let buf = path_to_c_string(filename); - let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()) - .ok_or_else(|| format!("error reading library: '{}'", filename.display()))?; - let of = - ObjectFile::new(mb).map(|of| OwningRef::new(Box::new(of))).ok_or_else(|| { - format!("provided path not an object file: '{}'", filename.display()) - })?; - let buf = of.try_map(|of| search_meta_section(of, target, filename))?; - Ok(rustc_erase_owner!(buf)) - } - } -} - -fn search_meta_section<'a>( - of: &'a ObjectFile, - target: &Target, - filename: &Path, -) -> Result<&'a [u8], String> { - unsafe { - let si = mk_section_iter(of.llof); - while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { - let mut name_buf = None; - let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf); - let name = name_buf.map_or_else( - String::new, // We got a null ptr, ignore `name_len`. - |buf| { - String::from_utf8( - slice::from_raw_parts(buf.as_ptr() as *const u8, name_len as usize) - .to_vec(), - ) - .unwrap() - }, - ); - debug!("get_metadata_section: name {}", name); - if read_metadata_section_name(target) == name { - let cbuf = llvm::LLVMGetSectionContents(si.llsi); - let csz = llvm::LLVMGetSectionSize(si.llsi) as usize; - // The buffer is valid while the object file is around - let buf: &'a [u8] = slice::from_raw_parts(cbuf as *const u8, csz); - return Ok(buf); - } - llvm::LLVMMoveToNextSection(si.llsi); - } - } - Err(format!("metadata not found: '{}'", filename.display())) -} - pub fn metadata_section_name(target: &Target) -> &'static str { // Historical note: // @@ -106,7 +21,3 @@ pub fn metadata_section_name(target: &Target) -> &'static str { if target.is_like_osx { "__DATA,.rustc" } else { ".rustc" } } - -fn read_metadata_section_name(_target: &Target) -> &'static str { - ".rustc" -} diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 7a3d715df6dcd..d7d91d09cfa9f 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -16,6 +16,7 @@ libc = "0.2.50" jobserver = "0.1.22" tempfile = "3.2" pathdiff = "0.2.0" +object = "0.22.0" rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs new file mode 100644 index 0000000000000..096098fb260c7 --- /dev/null +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -0,0 +1,65 @@ +//! Reading of the rustc metadata for rlibs and dylibs + +use std::fs::File; +use std::path::Path; + +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_target::spec::Target; + +use crate::METADATA_FILENAME; + +/// The default metadata loader. This is used by cg_llvm and cg_clif. +/// +/// # Metadata location +/// +///
+///
rlib
+///
The metadata can be found in the `lib.rmeta` file inside of the ar archive.
+///
dylib
+///
The metadata can be found in the `.rustc` section of the shared library.
+///
+pub struct DefaultMetadataLoader; + +fn load_metadata_with( + path: &Path, + f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>, +) -> Result { + 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 DefaultMetadataLoader { + fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result { + 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 { + 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)) + }) + } +} diff --git a/compiler/rustc_codegen_ssa/src/back/mod.rs b/compiler/rustc_codegen_ssa/src/back/mod.rs index 20ca503d43f45..d11ed54eb209f 100644 --- a/compiler/rustc_codegen_ssa/src/back/mod.rs +++ b/compiler/rustc_codegen_ssa/src/back/mod.rs @@ -3,6 +3,7 @@ pub mod command; pub mod link; pub mod linker; pub mod lto; +pub mod metadata; pub mod rpath; pub mod symbol_export; pub mod write; From f5d388302b045f60a417b906f80c00d46db99ee5 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 29 Mar 2021 13:02:59 +0200 Subject: [PATCH 2/8] Remove cg_llvm::metadata module --- compiler/rustc_codegen_llvm/src/base.rs | 17 +++++++++++++-- compiler/rustc_codegen_llvm/src/lib.rs | 1 - compiler/rustc_codegen_llvm/src/metadata.rs | 23 --------------------- 3 files changed, 15 insertions(+), 26 deletions(-) delete mode 100644 compiler/rustc_codegen_llvm/src/metadata.rs diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 6f6c649bb0b18..aeb0561c08620 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -18,7 +18,6 @@ use crate::builder::Builder; use crate::common; use crate::context::CodegenCx; use crate::llvm; -use crate::metadata; use crate::value::Value; use rustc_codegen_ssa::base::maybe_create_entry_wrapper; @@ -47,6 +46,21 @@ pub fn write_compressed_metadata<'tcx>( use snap::write::FrameEncoder; use std::io::Write; + // Historical note: + // + // When using link.exe it was seen that the section name `.note.rustc` + // was getting shortened to `.note.ru`, and according to the PE and COFF + // specification: + // + // > Executable images do not use a string table and do not support + // > section names longer than 8 characters + // + // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format + // + // As a result, we choose a slightly shorter name! As to why + // `.note.rustc` works on MinGW, that's another good question... + let section_name = if tcx.sess.target.is_like_osx { "__DATA,.rustc" } else { ".rustc" }; + let (metadata_llcx, metadata_llmod) = (&*llvm_module.llcx, llvm_module.llmod()); let mut compressed = tcx.metadata_encoding_version(); FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap(); @@ -59,7 +73,6 @@ pub fn write_compressed_metadata<'tcx>( unsafe { llvm::LLVMAddGlobal(metadata_llmod, common::val_ty(llconst), buf.as_ptr()) }; unsafe { llvm::LLVMSetInitializer(llglobal, llconst); - let section_name = metadata::metadata_section_name(&tcx.sess.target); let name = SmallCStr::new(section_name); llvm::LLVMSetSection(llglobal, name.as_ptr()); diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 8f95afc1b9181..4f8ea50acaabc 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -69,7 +69,6 @@ pub mod llvm { } mod llvm_util; -mod metadata; mod mono_item; mod type_; mod type_of; diff --git a/compiler/rustc_codegen_llvm/src/metadata.rs b/compiler/rustc_codegen_llvm/src/metadata.rs deleted file mode 100644 index 4bad93a75674b..0000000000000 --- a/compiler/rustc_codegen_llvm/src/metadata.rs +++ /dev/null @@ -1,23 +0,0 @@ -use rustc_target::spec::Target; - -use rustc_fs_util::path_to_c_string; -use std::path::Path; -use std::slice; - -pub fn metadata_section_name(target: &Target) -> &'static str { - // Historical note: - // - // When using link.exe it was seen that the section name `.note.rustc` - // was getting shortened to `.note.ru`, and according to the PE and COFF - // specification: - // - // > Executable images do not use a string table and do not support - // > section names longer than 8 characters - // - // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format - // - // As a result, we choose a slightly shorter name! As to why - // `.note.rustc` works on MinGW, that's another good question... - - if target.is_like_osx { "__DATA,.rustc" } else { ".rustc" } -} From 3ae15ca04f1ba5db8864b08203462e472cf8630a Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 29 Mar 2021 13:22:35 +0200 Subject: [PATCH 3/8] Allow wasmparser dependency --- src/tools/tidy/src/deps.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 064dd716521f5..5f4ba71d91a15 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -42,6 +42,7 @@ const EXCEPTIONS: &[(&str, &str)] = &[ ("snap", "BSD-3-Clause"), // rustc // FIXME: this dependency violates the documentation comment above: ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target + ("wasmparser", "Apache-2.0 WITH LLVM-exception"), // rustc ]; const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[ @@ -222,6 +223,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "vcpkg", "version_check", "wasi", + "wasmparser", "winapi", "winapi-build", "winapi-i686-pc-windows-gnu", From 802fe1756b9fdd6011e17ee6502d6909d2ce55ed Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 7 May 2021 18:57:22 +0200 Subject: [PATCH 4/8] Disable wasm feature of object in cg_ssa The version 1 resolver unifies enabled features across the whole workspace. This includes libstd which isn't allowed to depend on wasmparser. --- compiler/rustc_codegen_ssa/Cargo.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index d7d91d09cfa9f..3fad41f431904 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -16,7 +16,6 @@ libc = "0.2.50" jobserver = "0.1.22" tempfile = "3.2" pathdiff = "0.2.0" -object = "0.22.0" rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } @@ -34,3 +33,8 @@ rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_target = { path = "../rustc_target" } rustc_session = { path = "../rustc_session" } + +[dependencies.object] +version = "0.22.0" +default-features = false +features = ["read_core", "elf", "macho", "pe", "unaligned", "archive"] From b65a92fdd8b430a1ea421a5bbff08935787999fb Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 10 May 2021 09:46:02 +0200 Subject: [PATCH 5/8] Remove wasmparser --- Cargo.lock | 8 -------- src/tools/tidy/src/deps.rs | 2 -- 2 files changed, 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc688e3a513cc..189a3b0786c90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2348,10 +2348,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" dependencies = [ "compiler_builtins", - "flate2", "rustc-std-workspace-alloc", "rustc-std-workspace-core", - "wasmparser", ] [[package]] @@ -5621,12 +5619,6 @@ dependencies = [ "rustc-std-workspace-core", ] -[[package]] -name = "wasmparser" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32fddd575d477c6e9702484139cf9f23dcd554b06d185ed0f56c857dd3a47aa6" - [[package]] name = "winapi" version = "0.2.8" diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 5f4ba71d91a15..064dd716521f5 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -42,7 +42,6 @@ const EXCEPTIONS: &[(&str, &str)] = &[ ("snap", "BSD-3-Clause"), // rustc // FIXME: this dependency violates the documentation comment above: ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target - ("wasmparser", "Apache-2.0 WITH LLVM-exception"), // rustc ]; const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[ @@ -223,7 +222,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "vcpkg", "version_check", "wasi", - "wasmparser", "winapi", "winapi-build", "winapi-i686-pc-windows-gnu", From 487427fbe67480ee7248d775c4ffecd21df12626 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 10 May 2021 09:49:42 +0200 Subject: [PATCH 6/8] Better error messages --- .../rustc_codegen_ssa/src/back/metadata.rs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 096098fb260c7..37d1f8ecc8328 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -28,8 +28,10 @@ fn load_metadata_with( path: &Path, f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>, ) -> Result { - let file = File::open(path).map_err(|e| format!("{:?}", e))?; - let data = unsafe { Mmap::map(file) }.map_err(|e| format!("{:?}", e))?; + let file = + File::open(path).map_err(|e| format!("failed to open file '{}': {}", path.display(), e))?; + let data = unsafe { Mmap::map(file) } + .map_err(|e| format!("failed to mmap file '{}': {}", path.display(), e))?; let metadata = OwningRef::new(data).try_map(f)?; return Ok(rustc_erase_owner!(metadata.map_owner_box())); } @@ -38,16 +40,17 @@ impl MetadataLoader for DefaultMetadataLoader { fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result { load_metadata_with(path, |data| { let archive = object::read::archive::ArchiveFile::parse(&*data) - .map_err(|e| format!("{:?}", e))?; + .map_err(|e| format!("failed to parse rlib '{}': {}", path.display(), e))?; for entry_result in archive.members() { - let entry = entry_result.map_err(|e| format!("{:?}", e))?; + let entry = entry_result + .map_err(|e| format!("failed to parse rlib '{}': {}", path.display(), e))?; if entry.name() == METADATA_FILENAME.as_bytes() { return Ok(entry.data()); } } - Err("couldn't find metadata entry".to_string()) + Err(format!("metadata not found in rlib '{}'", path.display())) }) } @@ -55,11 +58,14 @@ impl MetadataLoader for DefaultMetadataLoader { use object::{Object, ObjectSection}; load_metadata_with(path, |data| { - let file = object::File::parse(&data).map_err(|e| format!("parse: {:?}", e))?; + let file = object::File::parse(&data) + .map_err(|e| format!("failed to parse dylib '{}': {}", path.display(), e))?; file.section_by_name(".rustc") - .ok_or("no .rustc section")? + .ok_or_else(|| format!("no .rustc section in '{}'", path.display()))? .data() - .map_err(|e| format!("failed to read .rustc section: {:?}", e)) + .map_err(|e| { + format!("failed to read .rustc section in '{}': {}", path.display(), e) + }) }) } } From 537e814d9c22d69868272cd472bf30164700c402 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 10 May 2021 10:49:45 +0200 Subject: [PATCH 7/8] Add link to historic note --- compiler/rustc_codegen_llvm/src/base.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index aeb0561c08620..893c909b20416 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -58,7 +58,8 @@ pub fn write_compressed_metadata<'tcx>( // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format // // As a result, we choose a slightly shorter name! As to why - // `.note.rustc` works on MinGW, that's another good question... + // `.note.rustc` works on MinGW, see + // https://github.com/llvm/llvm-project/blob/llvmorg-12.0.0/lld/COFF/Writer.cpp#L1190-L1197 let section_name = if tcx.sess.target.is_like_osx { "__DATA,.rustc" } else { ".rustc" }; let (metadata_llcx, metadata_llmod) = (&*llvm_module.llcx, llvm_module.llmod()); From 6381aaf8ae2df01cdb70b6f3123153cf4f1e03cd Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 13 May 2021 13:03:59 +0200 Subject: [PATCH 8/8] Use DefaultMetadataLoader in the hotplug_codegen_backend test --- .../hotplug_codegen_backend/the_backend.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index 0e1bef6f68d53..fce1835c4b2e8 100644 --- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -28,23 +28,11 @@ use rustc_target::spec::Target; use std::any::Any; use std::path::Path; -pub struct NoLlvmMetadataLoader; - -impl MetadataLoader for NoLlvmMetadataLoader { - fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result { - unreachable!("some_crate.rs shouldn't depend on any external crates"); - } - - fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result { - unreachable!("some_crate.rs shouldn't depend on any external crates"); - } -} - struct TheBackend; impl CodegenBackend for TheBackend { fn metadata_loader(&self) -> Box { - Box::new(NoLlvmMetadataLoader) + Box::new(rustc_codegen_ssa::back::metadata::DefaultMetadataLoader) } fn provide(&self, providers: &mut Providers) {}