Skip to content

Commit 92610ca

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

10 files changed

Lines changed: 142 additions & 48 deletions

File tree

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,9 @@ 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<Option<String>> =
315+
crate_info.used_libraries_filenames.iter().map(|f| f.map(|s| s.to_string())).collect();
316+
let metadata_link = rmeta_link::RmetaLink { rust_object_files, native_lib_filenames };
315317
let metadata_link_data = metadata_link.encode();
316318
let (wrapper, _) =
317319
create_wrapper_file(sess, rmeta_link::SECTION.to_string(), &metadata_link_data);
@@ -386,12 +388,12 @@ fn link_rlib<'a>(
386388
// feature then we'll need to figure out how to record what objects were
387389
// loaded from the libraries found here and then encode that into the
388390
// metadata of the rlib we're generating somehow.
389-
for lib in crate_info.used_libraries.iter() {
391+
for (i, lib) in crate_info.used_libraries.iter().enumerate() {
390392
let NativeLibKind::Static { bundle: None | Some(true), .. } = lib.kind else {
391393
continue;
392394
};
393395
if flavor == RlibFlavor::Normal
394-
&& let Some(filename) = lib.filename
396+
&& let Some(filename) = crate_info.used_libraries_filenames[i]
395397
{
396398
let path = find_native_static_library(filename.as_str(), true, sess);
397399
let src = read(path)
@@ -504,11 +506,16 @@ fn link_staticlib(
504506
let lto = are_upstream_rust_objects_already_included(sess)
505507
&& !ignored_for_lto(sess, crate_info, cnum);
506508

507-
let native_libs = crate_info.native_libraries[&cnum].iter();
508-
let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib));
509-
let relevant_libs: FxIndexSet<_> = relevant.filter_map(|lib| lib.filename).collect();
509+
let native_libs = &crate_info.native_libraries[&cnum];
510+
let filenames = &crate_info.native_libraries_filenames[&cnum];
511+
let relevant_libs: FxIndexSet<_> = native_libs
512+
.iter()
513+
.zip(filenames.iter())
514+
.filter(|(lib, _)| relevant_lib(sess, lib))
515+
.filter_map(|(_, f)| *f)
516+
.collect();
510517

511-
let bundled_libs: FxIndexSet<_> = native_libs.filter_map(|lib| lib.filename).collect();
518+
let bundled_libs: FxIndexSet<_> = filenames.iter().filter_map(|f| *f).collect();
512519
ab.add_archive(
513520
path,
514521
Some(Box::new(move |fname: &str, metadata_link| {
@@ -2893,13 +2900,13 @@ fn add_native_libs_from_crate(
28932900
.unwrap_or_else(|e| sess.dcx().emit_fatal(e));
28942901
}
28952902

2896-
let native_libs = match cnum {
2897-
LOCAL_CRATE => &crate_info.used_libraries,
2898-
_ => &crate_info.native_libraries[&cnum],
2903+
let (native_libs, filenames): (&Vec<NativeLib>, &Vec<Option<Symbol>>) = match cnum {
2904+
LOCAL_CRATE => (&crate_info.used_libraries, &crate_info.used_libraries_filenames),
2905+
_ => (&crate_info.native_libraries[&cnum], &crate_info.native_libraries_filenames[&cnum]),
28992906
};
29002907

29012908
let mut last = (None, NativeLibKind::Unspecified, false);
2902-
for lib in native_libs {
2909+
for (i, lib) in native_libs.iter().enumerate() {
29032910
if !relevant_lib(sess, lib) {
29042911
continue;
29052912
}
@@ -2919,7 +2926,7 @@ fn add_native_libs_from_crate(
29192926
let bundle = bundle.unwrap_or(true);
29202927
let whole_archive = whole_archive == Some(true);
29212928
if bundle && cnum != LOCAL_CRATE {
2922-
if let Some(filename) = lib.filename {
2929+
if let Some(filename) = filenames[i] {
29232930
// If rlib contains native libs as archives, they are unpacked to tmpdir.
29242931
let path = tmpdir.join(filename.as_str());
29252932
cmd.link_staticlib_by_path(&path, whole_archive);
@@ -3040,9 +3047,9 @@ fn add_upstream_rust_crates(
30403047
match linkage {
30413048
Linkage::Static | Linkage::IncludedFromDylib | Linkage::NotLinked => {
30423049
if link_static_crate {
3043-
bundled_libs = crate_info.native_libraries[&cnum]
3050+
bundled_libs = crate_info.native_libraries_filenames[&cnum]
30443051
.iter()
3045-
.filter_map(|lib| lib.filename)
3052+
.filter_map(|f| *f)
30463053
.collect();
30473054
add_static_crate(
30483055
cmd,

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<Option<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: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,28 @@ pub(crate) const SECTION: &str = ".rmeta-link";
1616

1717
pub struct RmetaLink {
1818
pub rust_object_files: Vec<String>,
19+
pub native_lib_filenames: Vec<Option<String>>,
1920
}
2021

2122
impl RmetaLink {
2223
pub(crate) fn encode(&self) -> Vec<u8> {
2324
let mut encoder = MemEncoder::new();
2425
self.rust_object_files.encode(&mut encoder);
26+
self.native_lib_filenames.encode(&mut encoder);
2527
let mut data = encoder.finish();
2628
data.extend_from_slice(MAGIC_END_BYTES);
2729
data
2830
}
2931

3032
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 })
33+
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
34+
let mut decoder = MemDecoder::new(data, 0).ok()?;
35+
let rust_object_files = Vec::<String>::decode(&mut decoder);
36+
let native_lib_filenames = Vec::<Option<String>>::decode(&mut decoder);
37+
Some(RmetaLink { rust_object_files, native_lib_filenames })
38+
}))
39+
.ok()
40+
.flatten()
3441
}
3542
}
3643

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc_hir::attrs::{DebuggerVisualizerType, OptimizeAttr};
1717
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1818
use rustc_hir::lang_items::LangItem;
1919
use rustc_hir::{ItemId, Target, find_attr};
20+
use rustc_metadata::creader::CStore;
2021
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
2122
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
2223
use rustc_middle::middle::dependency_format::Dependencies;
@@ -50,7 +51,8 @@ use crate::mir::operand::OperandValue;
5051
use crate::mir::place::PlaceRef;
5152
use crate::traits::*;
5253
use crate::{
53-
CachedModuleCodegen, CodegenLintLevelSpecs, CrateInfo, ModuleCodegen, errors, meth, mir,
54+
CachedModuleCodegen, CodegenLintLevelSpecs, CrateInfo, ModuleCodegen, NativeLib, errors, meth,
55+
mir,
5456
};
5557

5658
pub(crate) fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate {
@@ -948,7 +950,9 @@ impl CrateInfo {
948950
profiler_runtime: None,
949951
is_no_builtins: Default::default(),
950952
native_libraries: Default::default(),
953+
native_libraries_filenames: Default::default(),
951954
used_libraries: tcx.native_libraries(LOCAL_CRATE).iter().map(Into::into).collect(),
955+
used_libraries_filenames: tcx.native_library_filenames(LOCAL_CRATE).clone(),
952956
crate_name: UnordMap::with_capacity(n_crates),
953957
used_crates,
954958
used_crate_source: UnordMap::with_capacity(n_crates),
@@ -964,11 +968,24 @@ impl CrateInfo {
964968
info.native_libraries.reserve(n_crates);
965969

966970
for &cnum in crates.iter() {
967-
info.native_libraries
968-
.insert(cnum, tcx.native_libraries(cnum).iter().map(Into::into).collect());
969-
info.crate_name.insert(cnum, tcx.crate_name(cnum));
970-
971+
let native_libs: Vec<NativeLib> =
972+
tcx.native_libraries(cnum).iter().map(Into::into).collect();
971973
let used_crate_source = tcx.used_crate_source(cnum);
974+
let mut filenames_vec: Vec<Option<Symbol>> = vec![None; native_libs.len()];
975+
if let Some(rlib_path) = used_crate_source.rlib.as_ref() {
976+
let cstore = CStore::from_tcx(tcx);
977+
let filenames = cstore
978+
.metadata_loader()
979+
.get_rlib_native_lib_filenames(&tcx.sess.target, rlib_path);
980+
for (out, raw) in filenames_vec.iter_mut().zip(filenames.iter()) {
981+
if let Some(name) = raw {
982+
*out = Some(Symbol::intern(name));
983+
}
984+
}
985+
}
986+
info.native_libraries.insert(cnum, native_libs);
987+
info.native_libraries_filenames.insert(cnum, filenames_vec);
988+
info.crate_name.insert(cnum, tcx.crate_name(cnum));
972989
info.used_crate_source.insert(cnum, Arc::clone(used_crate_source));
973990
if tcx.is_profiler_runtime(cnum) {
974991
info.profiler_runtime = Some(cnum);

compiler/rustc_codegen_ssa/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,6 @@ bitflags::bitflags! {
208208
pub struct NativeLib {
209209
pub kind: NativeLibKind,
210210
pub name: Symbol,
211-
pub filename: Option<Symbol>,
212211
pub cfg: Option<CfgEntry>,
213212
pub verbatim: bool,
214213
pub dll_imports: Vec<cstore::DllImport>,
@@ -218,7 +217,6 @@ impl From<&cstore::NativeLib> for NativeLib {
218217
fn from(lib: &cstore::NativeLib) -> Self {
219218
NativeLib {
220219
kind: lib.kind,
221-
filename: lib.filename,
222220
name: lib.name,
223221
cfg: lib.cfg.clone(),
224222
verbatim: lib.verbatim.unwrap_or(false),
@@ -248,8 +246,10 @@ pub struct CrateInfo {
248246
pub profiler_runtime: Option<CrateNum>,
249247
pub is_no_builtins: FxHashSet<CrateNum>,
250248
pub native_libraries: FxIndexMap<CrateNum, Vec<NativeLib>>,
249+
pub native_libraries_filenames: FxIndexMap<CrateNum, Vec<Option<Symbol>>>,
251250
pub crate_name: UnordMap<CrateNum, Symbol>,
252251
pub used_libraries: Vec<NativeLib>,
252+
pub used_libraries_filenames: Vec<Option<Symbol>>,
253253
pub used_crate_source: UnordMap<CrateNum, Arc<CrateSource>>,
254254
pub used_crates: Vec<CrateNum>,
255255
pub dependency_formats: Arc<Dependencies>,

compiler/rustc_metadata/src/creader.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ 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+
fn get_rlib_native_lib_filenames(
57+
&self,
58+
_target: &Target,
59+
_filename: &Path,
60+
) -> Vec<Option<String>> {
61+
Vec::new()
62+
}
5563
}
5664

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

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

compiler/rustc_metadata/src/native_libs.rs

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ fn find_bundled_library(
184184
None
185185
}
186186

187-
pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec<NativeLib> {
187+
fn collect_pairs(tcx: TyCtxt<'_>) -> Vec<(NativeLib, Option<Symbol>)> {
188188
let mut collector = Collector { tcx, libs: Vec::new() };
189189
if tcx.sess.opts.unstable_opts.link_directives {
190190
for module in tcx.foreign_modules(LOCAL_CRATE).values() {
@@ -195,6 +195,14 @@ pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec<NativeLib>
195195
collector.libs
196196
}
197197

198+
pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec<NativeLib> {
199+
collect_pairs(tcx).into_iter().map(|(lib, _)| lib).collect()
200+
}
201+
202+
pub(crate) fn collect_filenames(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec<Option<Symbol>> {
203+
collect_pairs(tcx).into_iter().map(|(_, f)| f).collect()
204+
}
205+
198206
pub(crate) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
199207
match lib.cfg {
200208
Some(ref cfg) => eval_config_entry(sess, cfg).as_bool(),
@@ -204,7 +212,7 @@ pub(crate) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
204212

205213
struct Collector<'tcx> {
206214
tcx: TyCtxt<'tcx>,
207-
libs: Vec<NativeLib>,
215+
libs: Vec<(NativeLib, Option<Symbol>)>,
208216
}
209217

210218
impl<'tcx> Collector<'tcx> {
@@ -252,15 +260,17 @@ impl<'tcx> Collector<'tcx> {
252260
attr.cfg.is_some(),
253261
self.tcx,
254262
);
255-
self.libs.push(NativeLib {
256-
name: attr.name,
263+
self.libs.push((
264+
NativeLib {
265+
name: attr.name,
266+
kind: attr.kind,
267+
cfg: attr.cfg.clone(),
268+
foreign_module: Some(def_id.to_def_id()),
269+
verbatim: attr.verbatim,
270+
dll_imports,
271+
},
257272
filename,
258-
kind: attr.kind,
259-
cfg: attr.cfg.clone(),
260-
foreign_module: Some(def_id.to_def_id()),
261-
verbatim: attr.verbatim,
262-
dll_imports,
263-
});
273+
));
264274
}
265275
}
266276

@@ -276,7 +286,7 @@ impl<'tcx> Collector<'tcx> {
276286
self.tcx.dcx().emit_err(errors::LibFrameworkApple);
277287
}
278288
if let Some(ref new_name) = lib.new_name {
279-
let any_duplicate = self.libs.iter().any(|n| n.name.as_str() == lib.name);
289+
let any_duplicate = self.libs.iter().any(|(n, _)| n.name.as_str() == lib.name);
280290
if new_name.is_empty() {
281291
self.tcx.dcx().emit_err(errors::EmptyRenamingTarget { lib_name: &lib.name });
282292
} else if !any_duplicate {
@@ -300,7 +310,7 @@ impl<'tcx> Collector<'tcx> {
300310
// can move them to the end of the list below.
301311
let mut existing = self
302312
.libs
303-
.extract_if(.., |lib| {
313+
.extract_if(.., |(lib, _)| {
304314
if lib.name.as_str() == passed_lib.name {
305315
// FIXME: This whole logic is questionable, whether modifiers are
306316
// involved or not, library reordering and kind overriding without
@@ -341,15 +351,17 @@ impl<'tcx> Collector<'tcx> {
341351
false,
342352
self.tcx,
343353
);
344-
self.libs.push(NativeLib {
345-
name,
354+
self.libs.push((
355+
NativeLib {
356+
name,
357+
kind: passed_lib.kind,
358+
cfg: None,
359+
foreign_module: None,
360+
verbatim: passed_lib.verbatim,
361+
dll_imports: Vec::new(),
362+
},
346363
filename,
347-
kind: passed_lib.kind,
348-
cfg: None,
349-
foreign_module: None,
350-
verbatim: passed_lib.verbatim,
351-
dll_imports: Vec::new(),
352-
});
364+
));
353365
} else {
354366
// Move all existing libraries with the same name to the
355367
// end of the command line.

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
440440
})
441441
},
442442
native_libraries: native_libs::collect,
443+
native_library_filenames: native_libs::collect_filenames,
443444
foreign_modules: foreign_modules::collect,
444445
externally_implementable_items: eii::collect,
445446

0 commit comments

Comments
 (0)