|
1 | | -//! Reading and writing of the rustc metadata for rlibs and dylibs |
| 1 | +//! Writing of the rustc metadata for dylibs |
2 | 2 |
|
3 | | -use std::fs::File; |
4 | | -use std::path::Path; |
5 | | - |
6 | | -use rustc_codegen_ssa::METADATA_FILENAME; |
7 | | -use rustc_data_structures::memmap::Mmap; |
8 | | -use rustc_data_structures::owning_ref::OwningRef; |
9 | | -use rustc_data_structures::rustc_erase_owner; |
10 | | -use rustc_data_structures::sync::MetadataRef; |
11 | | -use rustc_middle::middle::cstore::MetadataLoader; |
12 | 3 | use rustc_middle::ty::TyCtxt; |
13 | | -use rustc_target::spec::Target; |
14 | 4 |
|
15 | 5 | use crate::backend::WriteMetadata; |
16 | 6 |
|
17 | | -/// The metadata loader used by cg_clif. |
18 | | -/// |
19 | | -/// The metadata is stored in the same format as cg_llvm. |
20 | | -/// |
21 | | -/// # Metadata location |
22 | | -/// |
23 | | -/// <dl> |
24 | | -/// <dt>rlib</dt> |
25 | | -/// <dd>The metadata can be found in the `lib.rmeta` file inside of the ar archive.</dd> |
26 | | -/// <dt>dylib</dt> |
27 | | -/// <dd>The metadata can be found in the `.rustc` section of the shared library.</dd> |
28 | | -/// </dl> |
29 | | -pub(crate) struct CraneliftMetadataLoader; |
30 | | - |
31 | | -fn load_metadata_with( |
32 | | - path: &Path, |
33 | | - f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>, |
34 | | -) -> Result<MetadataRef, String> { |
35 | | - let file = File::open(path).map_err(|e| format!("{:?}", e))?; |
36 | | - let data = unsafe { Mmap::map(file) }.map_err(|e| format!("{:?}", e))?; |
37 | | - let metadata = OwningRef::new(data).try_map(f)?; |
38 | | - return Ok(rustc_erase_owner!(metadata.map_owner_box())); |
39 | | -} |
40 | | - |
41 | | -impl MetadataLoader for CraneliftMetadataLoader { |
42 | | - fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> { |
43 | | - load_metadata_with(path, |data| { |
44 | | - let archive = object::read::archive::ArchiveFile::parse(&*data) |
45 | | - .map_err(|e| format!("{:?}", e))?; |
46 | | - |
47 | | - for entry_result in archive.members() { |
48 | | - let entry = entry_result.map_err(|e| format!("{:?}", e))?; |
49 | | - if entry.name() == METADATA_FILENAME.as_bytes() { |
50 | | - return Ok(entry.data()); |
51 | | - } |
52 | | - } |
53 | | - |
54 | | - Err("couldn't find metadata entry".to_string()) |
55 | | - }) |
56 | | - } |
57 | | - |
58 | | - fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> { |
59 | | - use object::{Object, ObjectSection}; |
60 | | - |
61 | | - load_metadata_with(path, |data| { |
62 | | - let file = object::File::parse(&data).map_err(|e| format!("parse: {:?}", e))?; |
63 | | - file.section_by_name(".rustc") |
64 | | - .ok_or("no .rustc section")? |
65 | | - .data() |
66 | | - .map_err(|e| format!("failed to read .rustc section: {:?}", e)) |
67 | | - }) |
68 | | - } |
69 | | -} |
70 | | - |
71 | 7 | // Adapted from https://github.com/rust-lang/rust/blob/da573206f87b5510de4b0ee1a9c044127e409bd3/src/librustc_codegen_llvm/base.rs#L47-L112 |
72 | 8 | pub(crate) fn write_metadata<O: WriteMetadata>(tcx: TyCtxt<'_>, object: &mut O) { |
73 | 9 | use snap::write::FrameEncoder; |
|
0 commit comments