rustc_codegen_ssa/back/
rmeta_link.rs1use std::path::{Path, PathBuf};
6
7use object::read::archive::ArchiveFile;
8use rustc_data_structures::fx::FxHashMap;
9use rustc_serialize::opaque::mem_encoder::MemEncoder;
10use rustc_serialize::opaque::{MAGIC_END_BYTES, MemDecoder};
11use rustc_serialize::{Decodable, Encodable};
12
13use super::metadata::search_for_section;
14
15pub(crate) const FILENAME: &str = "lib.rmeta-link";
16pub(crate) const SECTION: &str = ".rmeta-link";
17
18pub struct RmetaLink {
19 pub rust_object_files: Vec<String>,
20}
21
22impl RmetaLink {
23 pub(crate) fn encode(&self) -> Vec<u8> {
24 let mut encoder = MemEncoder::new();
25 self.rust_object_files.encode(&mut encoder);
26 let mut data = encoder.finish();
27 data.extend_from_slice(MAGIC_END_BYTES);
28 data
29 }
30
31 pub(crate) fn decode(data: &[u8]) -> Option<RmetaLink> {
32 let mut decoder = MemDecoder::new(data, 0).ok()?;
33 let rust_object_files = Vec::<String>::decode(&mut decoder);
34 Some(RmetaLink { rust_object_files })
35 }
36}
37
38pub fn read(archive: &ArchiveFile<'_>, archive_data: &[u8], rlib_path: &Path) -> Option<RmetaLink> {
40 for entry in archive.members() {
41 let entry = entry.ok()?;
42 if entry.name() == FILENAME.as_bytes() {
43 let data = entry.data(archive_data).ok()?;
44 let section_data = search_for_section(rlib_path, data, SECTION).ok()?;
45 return RmetaLink::decode(section_data);
46 }
47 }
48 None
49}
50
51pub fn read_from_data(archive_data: &[u8], rlib_path: &Path) -> Option<RmetaLink> {
55 let archive = ArchiveFile::parse(archive_data).ok()?;
56 read(&archive, archive_data, rlib_path)
57}
58
59#[derive(#[automatically_derived]
impl ::core::default::Default for RmetaLinkCache {
#[inline]
fn default() -> RmetaLinkCache {
RmetaLinkCache { cache: ::core::default::Default::default() }
}
}Default)]
60pub struct RmetaLinkCache {
61 cache: FxHashMap<PathBuf, Option<RmetaLink>>,
62}
63
64impl RmetaLinkCache {
65 pub fn get_or_insert_with(
66 &mut self,
67 rlib_path: &Path,
68 load: impl FnOnce() -> Option<RmetaLink>,
69 ) -> Option<&RmetaLink> {
70 self.cache.entry(rlib_path.to_path_buf()).or_insert_with(load).as_ref()
71 }
72}