From 329e0994000ecdb5a3dfd468f08b37b67006647f Mon Sep 17 00:00:00 2001 From: Seth Junot Date: Sat, 8 Jul 2023 18:44:50 -0700 Subject: Support explicit 32-bit MIPS ABI for the synthetic object PR #95604 introduced a "synthetic object file to ensure all exported and used symbols participate in the linking". One constraint on this file is that for MIPS-based targets, its architecture-specific ELF flags must be the same as all other object files passed to the linker. That's enforced by LLD, here: https://github.com/llvm/llvm-project/blob/llvmorg-16.0.6/lld/ELF/Arch/MipsArchTree.cpp#L77 The current approach to determining e_flags for 32-bit was implemented in PR #96930, which links to this issue that summarizes the problem well: https://github.com/ayrtonm/psx-sdk-rs/issues/9 > ... the temporary object file is created with an e_flags which is > invalid for 32-bit MIPS targets. The main issue is that it omits the ABI > bits (EF_MIPS_ABI_O32) which implies it uses the N64 ABI. To enable the N32 MIPS ABI (which succeeded O32), this patch enables setting the synthetic object's ABI based on the target "llvm-abiname" field, if it's given; otherwise, the O32 ABI is assumed for 32-bit MIPS targets. More information about the N32 ABI can be found here: https://web.archive.org/web/20160121005457/http://techpubs.sgi.com/library/manuals/2000/007-2816-005/pdf/007-2816-005.pdf --- compiler/rustc_codegen_ssa/src/back/metadata.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 00e6acb5c1a..a463dff852d 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -243,8 +243,16 @@ pub(crate) fn create_object_file(sess: &Session) -> Option elf::EF_MIPS_ARCH_32R6, _ => elf::EF_MIPS_ARCH_32R2, }; - // The only ABI LLVM supports for 32-bit MIPS CPUs is o32. - let mut e_flags = elf::EF_MIPS_CPIC | elf::EF_MIPS_ABI_O32 | arch; + + let mut e_flags = elf::EF_MIPS_CPIC | arch; + + // If the ABI is explicitly given, use it or default to O32. + match sess.target.options.llvm_abiname.to_lowercase().as_str() { + "n32" => e_flags |= elf::EF_MIPS_ABI2, + "o32" => e_flags |= elf::EF_MIPS_ABI_O32, + _ => e_flags |= elf::EF_MIPS_ABI_O32, + }; + if sess.target.options.relocation_model != RelocModel::Static { e_flags |= elf::EF_MIPS_PIC; } -- cgit 1.4.1-3-g733a5 From 650243977beb19a9e168626e3421578c000d21d9 Mon Sep 17 00:00:00 2001 From: Charisee Date: Tue, 11 Jul 2023 23:48:18 +0000 Subject: Use constants from object crate Replace hard-coded values with GNU_PROPERTY_{X86|AARCH64}_FEATURE_1_AND from the object crate. --- compiler/rustc_codegen_ssa/src/back/metadata.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index a463dff852d..1f827a2375d 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -12,7 +12,6 @@ use object::{ use snap::write::FrameEncoder; -use object::elf::NT_GNU_PROPERTY_TYPE_0; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice}; use rustc_metadata::fs::METADATA_FILENAME; @@ -124,7 +123,7 @@ fn add_gnu_property_note( let mut data: Vec = Vec::new(); let n_namsz: u32 = 4; // Size of the n_name field let n_descsz: u32 = 16; // Size of the n_desc field - let n_type: u32 = NT_GNU_PROPERTY_TYPE_0; // Type of note descriptor + let n_type: u32 = object::elf::NT_GNU_PROPERTY_TYPE_0; // Type of note descriptor let header_values = [n_namsz, n_descsz, n_type]; header_values.iter().for_each(|v| { data.extend_from_slice(&match endianness { @@ -134,8 +133,8 @@ fn add_gnu_property_note( }); data.extend_from_slice(b"GNU\0"); // Owner of the program property note let pr_type: u32 = match architecture { - Architecture::X86_64 => 0xc0000002, - Architecture::Aarch64 => 0xc0000000, + Architecture::X86_64 => object::elf::GNU_PROPERTY_X86_FEATURE_1_AND, + Architecture::Aarch64 => object::elf::GNU_PROPERTY_AARCH64_FEATURE_1_AND, _ => unreachable!(), }; let pr_datasz: u32 = 4; //size of the pr_data field -- cgit 1.4.1-3-g733a5