From 267d55d44acf6bb2821de39d4f868650ff0a9c7b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 29 Mar 2021 11:39:13 +0200 Subject: Use the object crate for metadata reading --- compiler/rustc_codegen_llvm/src/lib.rs | 2 +- compiler/rustc_codegen_llvm/src/metadata.rs | 89 ----------------------------- 2 files changed, 1 insertion(+), 90 deletions(-) (limited to 'compiler/rustc_codegen_llvm') diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 5ca4b226c38..8f95afc1b91 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 decc1e1f700..4bad93a7567 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" -} -- cgit 1.4.1-3-g733a5 From f5d388302b045f60a417b906f80c00d46db99ee5 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 29 Mar 2021 13:02:59 +0200 Subject: 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 (limited to 'compiler/rustc_codegen_llvm') diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 6f6c649bb0b..aeb0561c086 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 8f95afc1b91..4f8ea50acaa 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 4bad93a7567..00000000000 --- 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" } -} -- cgit 1.4.1-3-g733a5 From 537e814d9c22d69868272cd472bf30164700c402 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 10 May 2021 10:49:45 +0200 Subject: Add link to historic note --- compiler/rustc_codegen_llvm/src/base.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'compiler/rustc_codegen_llvm') diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index aeb0561c086..893c909b204 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()); -- cgit 1.4.1-3-g733a5