Skip to content

Commit

Permalink
Support explicit 32-bit MIPS ABI for the synthetic object
Browse files Browse the repository at this point in the history
PR rust-lang#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 rust-lang#96930, which links to this issue that summarizes the problem well:
ayrtonm/psx-sdk-rs#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
  • Loading branch information
xSetech committed Jul 9, 2023
1 parent b12ff66 commit 329e099
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions compiler/rustc_codegen_ssa/src/back/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,16 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
s if s.contains("r6") => 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;
}
Expand Down

0 comments on commit 329e099

Please sign in to comment.