Skip to content

Commit 5a93c75

Browse files
committed
Move NativeLib::filename to the rmeta-link archive member
1 parent ca9203f commit 5a93c75

12 files changed

Lines changed: 169 additions & 8 deletions

File tree

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,12 @@ fn link_rlib<'a>(
311311
.collect();
312312

313313
let metadata_link_file = if matches!(flavor, RlibFlavor::Normal) {
314-
let metadata_link = rmeta_link::RmetaLink { rust_object_files };
314+
let native_lib_filenames: Vec<(String, String)> = crate_info
315+
.used_libraries
316+
.iter()
317+
.filter_map(|lib| Some((lib.name.to_string(), lib.filename?.to_string())))
318+
.collect();
319+
let metadata_link = rmeta_link::RmetaLink { rust_object_files, native_lib_filenames };
315320
let metadata_link_data = metadata_link.encode();
316321
let (wrapper, _) =
317322
create_wrapper_file(sess, rmeta_link::SECTION.to_string(), &metadata_link_data);

compiler/rustc_codegen_ssa/src/back/metadata.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,41 @@ impl MetadataLoader for DefaultMetadataLoader {
103103
load_metadata_with(path, |data| search_for_section(path, data, ".rustc"))
104104
}
105105
}
106+
107+
fn get_rlib_native_lib_filenames(&self, target: &Target, path: &Path) -> Vec<(String, String)> {
108+
debug!("getting rmeta-link native lib filenames for {}", path.display());
109+
let Ok(file) = File::open(path) else {
110+
debug!("failed to open rlib for native-lib filenames: {}", path.display());
111+
return Vec::new();
112+
};
113+
let Ok(mmap) = (unsafe { Mmap::map(file) }) else {
114+
debug!("failed to mmap rlib for native-lib filenames: {}", path.display());
115+
return Vec::new();
116+
};
117+
118+
if target.is_like_aix {
119+
let Ok(archive) = object::read::archive::ArchiveFile::parse(&*mmap) else {
120+
return Vec::new();
121+
};
122+
for entry in archive.members() {
123+
let Ok(entry) = entry else { continue };
124+
if entry.name() == super::rmeta_link::FILENAME.as_bytes() {
125+
let Ok(member_data) = entry.data(&*mmap) else { continue };
126+
let Ok(section_data) = get_metadata_xcoff(path, member_data) else {
127+
continue;
128+
};
129+
return super::rmeta_link::RmetaLink::decode(section_data)
130+
.map(|rl| rl.native_lib_filenames)
131+
.unwrap_or_default();
132+
}
133+
}
134+
return Vec::new();
135+
}
136+
137+
super::rmeta_link::read_from_data(&mmap, path)
138+
.map(|rl| rl.native_lib_filenames)
139+
.unwrap_or_default()
140+
}
106141
}
107142

108143
pub(super) fn search_for_section<'a>(

compiler/rustc_codegen_ssa/src/back/rmeta_link.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,29 @@ pub(crate) const SECTION: &str = ".rmeta-link";
1616

1717
pub struct RmetaLink {
1818
pub rust_object_files: Vec<String>,
19+
/// `(NativeLib::name, filename)` pairs.
20+
pub native_lib_filenames: Vec<(String, String)>,
1921
}
2022

2123
impl RmetaLink {
2224
pub(crate) fn encode(&self) -> Vec<u8> {
2325
let mut encoder = MemEncoder::new();
2426
self.rust_object_files.encode(&mut encoder);
27+
self.native_lib_filenames.encode(&mut encoder);
2528
let mut data = encoder.finish();
2629
data.extend_from_slice(MAGIC_END_BYTES);
2730
data
2831
}
2932

3033
pub(crate) fn decode(data: &[u8]) -> Option<RmetaLink> {
31-
let mut decoder = MemDecoder::new(data, 0).ok()?;
32-
let rust_object_files = Vec::<String>::decode(&mut decoder);
33-
Some(RmetaLink { rust_object_files })
34+
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
35+
let mut decoder = MemDecoder::new(data, 0).ok()?;
36+
let rust_object_files = Vec::<String>::decode(&mut decoder);
37+
let native_lib_filenames = Vec::<(String, String)>::decode(&mut decoder);
38+
Some(RmetaLink { rust_object_files, native_lib_filenames })
39+
}))
40+
.ok()
41+
.flatten()
3442
}
3543
}
3644

compiler/rustc_metadata/src/creader.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ use crate::rmeta::{
5252
pub trait MetadataLoader {
5353
fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>;
5454
fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>;
55+
56+
/// `(NativeLib::name, filename)` pairs from `lib.rmeta-link`. Empty when absent.
57+
fn get_rlib_native_lib_filenames(
58+
&self,
59+
_target: &Target,
60+
_filename: &Path,
61+
) -> Vec<(String, String)> {
62+
Vec::new()
63+
}
5564
}
5665

5766
pub type MetadataLoaderDyn = dyn MetadataLoader + Send + Sync + sync::DynSend + sync::DynSync;
@@ -234,6 +243,10 @@ impl CStore {
234243
self.metas[cnum].as_ref().unwrap_or_else(|| panic!("Failed to get crate data for {cnum:?}"))
235244
}
236245

246+
pub(crate) fn metadata_loader(&self) -> &MetadataLoaderDyn {
247+
&*self.metadata_loader
248+
}
249+
237250
pub(crate) fn get_crate_data_mut(&mut self, cnum: CrateNum) -> &mut CrateMetadata {
238251
self.metas[cnum].as_mut().unwrap_or_else(|| panic!("Failed to get crate data for {cnum:?}"))
239252
}

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1458,7 +1458,22 @@ impl CrateMetadata {
14581458
}
14591459

14601460
fn get_native_libraries(&self, tcx: TyCtxt<'_>) -> impl Iterator<Item = NativeLib> {
1461-
self.root.native_libraries.decode((self, tcx))
1461+
let mut libs: Vec<NativeLib> = self.root.native_libraries.decode((self, tcx)).collect();
1462+
1463+
if let Some(rlib_path) = self.source().rlib.as_ref() {
1464+
let cstore = CStore::from_tcx(tcx);
1465+
let filenames =
1466+
cstore.metadata_loader().get_rlib_native_lib_filenames(&tcx.sess.target, rlib_path);
1467+
for lib in libs.iter_mut() {
1468+
if let Some((_, filename)) =
1469+
filenames.iter().find(|(name, _)| name == lib.name.as_str())
1470+
{
1471+
lib.filename = Some(Symbol::intern(filename));
1472+
}
1473+
}
1474+
}
1475+
1476+
libs.into_iter()
14621477
}
14631478

14641479
fn get_proc_macro_quoted_span(&self, tcx: TyCtxt<'_>, index: usize) -> Span {

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub(crate) fn rustc_version(cfg_version: &'static str) -> String {
6060
/// Metadata encoding version.
6161
/// N.B., increment this if you change the format of metadata such that
6262
/// the rustc version can't be found to compare with `rustc_version()`.
63-
const METADATA_VERSION: u8 = 10;
63+
const METADATA_VERSION: u8 = 11;
6464

6565
/// Metadata header which includes `METADATA_VERSION`.
6666
///

compiler/rustc_session/src/cstore.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_hir::def_id::{
1313
};
1414
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions};
1515
use rustc_macros::{BlobDecodable, Decodable, Encodable, StableHash};
16-
use rustc_span::{Span, Symbol};
16+
use rustc_span::{Span, SpanDecoder, SpanEncoder, Symbol};
1717

1818
// lonely orphan structs and enums looking for a better home
1919

@@ -64,18 +64,44 @@ pub enum LinkagePreference {
6464
RequireStatic,
6565
}
6666

67-
#[derive(Debug, Encodable, Decodable, StableHash)]
67+
#[derive(Debug, StableHash)]
6868
pub struct NativeLib {
6969
pub kind: NativeLibKind,
7070
pub name: Symbol,
7171
/// If packed_bundled_libs enabled, actual filename of library is stored.
72+
#[stable_hash(ignore)]
7273
pub filename: Option<Symbol>,
7374
pub cfg: Option<CfgEntry>,
7475
pub foreign_module: Option<DefId>,
7576
pub verbatim: Option<bool>,
7677
pub dll_imports: Vec<DllImport>,
7778
}
7879

80+
impl<E: SpanEncoder> rustc_serialize::Encodable<E> for NativeLib {
81+
fn encode(&self, s: &mut E) {
82+
self.kind.encode(s);
83+
self.name.encode(s);
84+
self.cfg.encode(s);
85+
self.foreign_module.encode(s);
86+
self.verbatim.encode(s);
87+
self.dll_imports.encode(s);
88+
}
89+
}
90+
91+
impl<D: SpanDecoder> rustc_serialize::Decodable<D> for NativeLib {
92+
fn decode(d: &mut D) -> Self {
93+
NativeLib {
94+
kind: rustc_serialize::Decodable::decode(d),
95+
name: rustc_serialize::Decodable::decode(d),
96+
filename: None,
97+
cfg: rustc_serialize::Decodable::decode(d),
98+
foreign_module: rustc_serialize::Decodable::decode(d),
99+
verbatim: rustc_serialize::Decodable::decode(d),
100+
dll_imports: rustc_serialize::Decodable::decode(d),
101+
}
102+
}
103+
}
104+
79105
impl NativeLib {
80106
pub fn has_modifiers(&self) -> bool {
81107
self.verbatim.is_some() || self.kind.has_modifiers()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
extern crate rust_dep;
2+
fn main() {
3+
assert_eq!(rust_dep::rust_dep(), 3);
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int native_fa() { return 1; }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int native_fb() { return 2; }

0 commit comments

Comments
 (0)