From 39f3adb3a542ac3d754304756d6a251e84260a82 Mon Sep 17 00:00:00 2001 From: mehdiakiki Date: Mon, 24 Aug 2026 21:17:46 +0100 Subject: [PATCH] Fix rmeta-link metadata not being read on AIX --- compiler/rustc_codegen_gcc/src/back/lto.rs | 10 +++-- compiler/rustc_codegen_llvm/src/back/lto.rs | 3 +- .../rustc_codegen_ssa/src/back/archive.rs | 7 +++- .../rustc_codegen_ssa/src/back/rmeta_link.rs | 40 +++++++++---------- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs index 98f9abdb05c4c..f28655bd630c7 100644 --- a/compiler/rustc_codegen_gcc/src/back/lto.rs +++ b/compiler/rustc_codegen_gcc/src/back/lto.rs @@ -45,7 +45,11 @@ struct LtoData { tmp_path: TempDir, } -fn prepare_lto(each_linked_rlib_for_lto: &[PathBuf], dcx: DiagCtxtHandle<'_>) -> LtoData { +fn prepare_lto( + each_linked_rlib_for_lto: &[PathBuf], + dcx: DiagCtxtHandle<'_>, + is_like_aix: bool, +) -> LtoData { let tmp_path = match tempdir() { Ok(tmp_path) => tmp_path, Err(error) => { @@ -64,7 +68,7 @@ fn prepare_lto(each_linked_rlib_for_lto: &[PathBuf], dcx: DiagCtxtHandle<'_>) -> let archive_data = unsafe { Mmap::map(File::open(path).expect("couldn't open rlib")).expect("couldn't map rlib") }; - let metadata_link = rmeta_link::read_from_data(&archive_data, path).unwrap(); + let metadata_link = rmeta_link::read_from_data(&archive_data, path, is_like_aix).unwrap(); let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib"); let obj_files = archive .members() @@ -110,7 +114,7 @@ pub(crate) fn run_fat( ) -> CompiledModule { let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); - let lto_data = prepare_lto(each_linked_rlib_for_lto, dcx); + let lto_data = prepare_lto(each_linked_rlib_for_lto, dcx, cgcx.target_is_like_aix); /*let symbols_below_threshold = lto_data.symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::>();*/ fat_lto( diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index db111926ca671..200e67b81e3cf 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -97,7 +97,8 @@ fn prepare_lto( .expect("couldn't map rlib") }; let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib"); - let metadata_link = rmeta_link::read(&archive, &archive_data, &path).unwrap(); + let metadata_link = + rmeta_link::read(&archive, &archive_data, &path, cgcx.target_is_like_aix).unwrap(); let obj_files = archive .members() .filter_map(|child| { diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 6c4575caebd8e..c51d1081ca5ae 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -491,7 +491,12 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> { }; let metadata_link = match &mut ar_kind { AddArchiveKind::Rlib(cache, _) => cache.get_or_insert_with(&archive_path, || { - rmeta_link::read(&archive, &archive_map, &archive_path) + rmeta_link::read( + &archive, + &archive_map, + &archive_path, + self.sess.target.is_like_aix, + ) }), AddArchiveKind::Other => None, }; diff --git a/compiler/rustc_codegen_ssa/src/back/rmeta_link.rs b/compiler/rustc_codegen_ssa/src/back/rmeta_link.rs index 59139214146c4..792219664cbf9 100644 --- a/compiler/rustc_codegen_ssa/src/back/rmeta_link.rs +++ b/compiler/rustc_codegen_ssa/src/back/rmeta_link.rs @@ -48,12 +48,21 @@ impl RmetaLink { } /// Reads the link-time metadata from an already-parsed archive. -pub fn read(archive: &ArchiveFile<'_>, archive_data: &[u8], rlib_path: &Path) -> Option { +pub fn read( + archive: &ArchiveFile<'_>, + archive_data: &[u8], + rlib_path: &Path, + is_like_aix: bool, +) -> Option { for entry in archive.members() { let entry = entry.ok()?; if entry.name() == FILENAME.as_bytes() { let data = entry.data(archive_data).ok()?; - let section_data = search_for_section(rlib_path, data, SECTION).ok()?; + let section_data = if is_like_aix { + get_metadata_xcoff(rlib_path, data).ok()? + } else { + search_for_section(rlib_path, data, SECTION).ok()? + }; return RmetaLink::decode(section_data); } } @@ -63,9 +72,13 @@ pub fn read(archive: &ArchiveFile<'_>, archive_data: &[u8], rlib_path: &Path) -> /// Like [`read`], but parses the archive from raw bytes. /// /// Use this when the caller's `ArchiveFile` comes from a different version of the `object` crate. -pub fn read_from_data(archive_data: &[u8], rlib_path: &Path) -> Option { +pub fn read_from_data( + archive_data: &[u8], + rlib_path: &Path, + is_like_aix: bool, +) -> Option { let archive = ArchiveFile::parse(archive_data).ok()?; - read(&archive, archive_data, rlib_path) + read(&archive, archive_data, rlib_path, is_like_aix) } #[derive(Default)] @@ -91,7 +104,7 @@ impl RmetaLinkCache { if !crate_may_have_bundled_libs(native_libs) { return Vec::new(); } - self.get_or_insert_with(rlib_path, || read_from_path(target, rlib_path)) + self.get_or_insert_with(rlib_path, || read_from_path(rlib_path, target.is_like_aix)) .map(|rl| { rl.native_lib_filenames.iter().map(|f| f.as_deref().map(Symbol::intern)).collect() }) @@ -105,7 +118,7 @@ fn crate_may_have_bundled_libs(libs: &[NativeLib]) -> bool { } // FIXME: this is mostly a copy-paste of `DefaultMetadataLoader::get_rlib_metadata`. -fn read_from_path(target: &Target, path: &Path) -> Option { +fn read_from_path(path: &Path, is_like_aix: bool) -> Option { let Ok(file) = File::open(path) else { debug!("failed to open rlib for rmeta-link: {}", path.display()); return None; @@ -115,18 +128,5 @@ fn read_from_path(target: &Target, path: &Path) -> Option { return None; }; - if target.is_like_aix { - let archive = ArchiveFile::parse(&*mmap).ok()?; - for entry in archive.members() { - let entry = entry.ok()?; - if entry.name() == FILENAME.as_bytes() { - let member_data = entry.data(&*mmap).ok()?; - let section_data = get_metadata_xcoff(path, member_data).ok()?; - return RmetaLink::decode(section_data); - } - } - return None; - } - - read_from_data(&mmap, path) + read_from_data(&mmap, path, is_like_aix) }